Slide 1

Slide 1 text

Random Ruby Tips and Rails 30

Slide 2

Slide 2 text

I Japan

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Winston @winstonyw

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

͔͜͜ΒӳޠΛ࢖͍·͢ɻ ͝ΊΜͳ͍͞ʂ

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

RubyAsia.com A fortnightly newsletter for Ruby news and articles from Asia

Slide 9

Slide 9 text

June 26 - 27, 2014 Singapore http://www.reddotrubyconf.com

Slide 10

Slide 10 text

SG Ruby Group http://www.meetup.com/Singapore-Ruby-Group/

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

Random Ruby Tips and Rails 30

Slide 15

Slide 15 text

Ruby Tips

Slide 16

Slide 16 text

>> "Hello World" => "Hello World” ! >> string = _ => "Hello World” ! >> string => "Hello World" #1 Underscore as Last Returned Value irb

Slide 17

Slide 17 text

>> n = 5000000 => 5000000 ! >> m = 5_000_000 => 5000000 ! >> n == m => true #2 Underscore as Separator irb

Slide 18

Slide 18 text

#3 Array Initialization Array(x).each do |x| puts x end if x.is_a? Array x.each { |x| puts x } else puts x end

Slide 19

Slide 19 text

#4 Hash Default >> hash = Hash.new(:default) ! >> hash[:not_found] => :default ! >> hash.fetch(:not_found) KeyError: key not found: :not_found irb

Slide 20

Slide 20 text

#5 Hash Fetch and Default >> hash = Hash.new ! >> hash.fetch(:not_found, :default) => :default ! >> hash.fetch(:not_found) {|e| "#{e} default"} => "not_found default" irb

Slide 21

Slide 21 text

Hash Map (1) >> hash.inject({}) do |new_hash, (k,v)| >> new_hash[k] = v*2 >> new_hash >> end => {:a => 2, :b => 4} irb Convert {a: 1, b: 2} To {a: 2, b: 4} #6

Slide 22

Slide 22 text

#7 Hash Map (2) >> Hash[hash.map{ |k,v| [k, v*2] }] => {:a => 2, :b => 4} ! >> hash.map{ |k,v| [k, v*2] } => [[:a, 2], [:b, 4]] ! >> Hash[[[:a, 2], [:b, 4]]] => {:a => 2, :b => 4} irb Convert {a: 1, b: 2} To {a: 2, b: 4}

Slide 23

Slide 23 text

#8 Hash Map (3) >> hash.merge(hash) { |key, oldval, newval| newval*2 } => {:a => 2, :b => 4} ! >> hash.merge(hash) { |_, _, newval| newval*2 } => {:a => 2, :b => 4} irb Convert {a: 1, b: 2} To {a: 2, b: 4}

Slide 24

Slide 24 text

#9 Case Conditions >> whichcase(1) => "I am an integer." >> whichcase("1") => "I am a string." >> whichcase(3) => "I am either 2 or 3." >> whichcase(4) => "I belong to a range." >> whichcase(8) => "I belong to a range." >> whichcase(20) => "I am 20!" >> whichcase(:nobody) => "I am nobody." irb def whichcase(num) case num when 1 "I am an integer." when "1" "I am a string." when 2, 3 "I am either 2 or 3." when 4..10 "I belong to a range." when ->(x) { x == 20 } "I am 20!" else "I am nobody." end end

Slide 25

Slide 25 text

>> %w(hello world).map { |s| s.upcase } => ["HELLO", “WORLD"] ! >> %w(hello world).map(&:upcase) => ["HELLO", "WORLD"] #10 Symbol to Proc to Block irb http://stackoverflow.com/questions/14881125/what-does-to-proc-method-mean

Slide 26

Slide 26 text

>> numbers = [1, 2, 3, 4] => [1, 2, 3, 4] ! >> numbers.inject(&:+) => 10 #11 Symbol to Proc to Block irb

Slide 27

Slide 27 text

>> %(hello world).map(&Star) >> ["** hello **", "** world **"] #12 Symbol to Proc to Block irb class Star def self.to_proc lambda { |x| "** #{x} **" } end end

Slide 28

Slide 28 text

#13 Exceptions Hierarchy def rescue_exception begin boom rescue Exception => e puts "Rescued: #{e}" end end Bad!!! Exception NoMemoryError ScriptError LoadError NotImplementedError SyntaxError SecurityError SignalException Interrupt StandardError ArgumentError EncodingError FiberError IOError IndexError KeyError StopIteration LocalJumpError NameError NoMethodError RangeError FloatDomainError RegexpError RuntimeError SystemCallError ThreadError TypeError ZeroDivisionError SystemExit SystemStackError fatal

Slide 29

Slide 29 text

#14 Rescue Refactoring def rescue_exception boom rescue NameError => e puts "Rescued: #{e}" end def rescue_exception begin boom rescue Exception => e puts "Rescued: #{e}" end end

Slide 30

Slide 30 text

Source Location #15 >> src = " ".method(:blank?).source_location => ["/vagrant/rails/activesupport/lib/active_support/ core_ext/object/blank.rb", 116] ! >> `subl #{src[0]}:#{src[1]}` ! >> " ".method(:slice).source_location => nil irb

Slide 31

Slide 31 text

$> ruby data.rb ! --> Read Data Position: 192 Hello World! --> Read Data Again Position: 192 Hello World! #16 Reading DATA in a Ruby File shell position = DATA.pos ! puts "--> Read Data" puts "Position: #{position}" puts DATA.read ! puts "--> Read Data Again" DATA.seek position puts "Position: #{position}" puts DATA.read ! __END__ Hello World!

Slide 32

Slide 32 text

$> echo "super\nsize\nme" | ruby -ne 'puts $_.upcase' SUPER SIZE ME #17 Command-line Ruby shell

Slide 33

Slide 33 text

$> ruby -run -e httpd . -p 8080 #18 Simple Ruby Server shell https://github.com/ruby/ruby/blob/trunk/lib/un.rb

Slide 34

Slide 34 text

>> require 'open-uri' ! >> big = open("http://localhost:8080/big.txt") => # ! >> small = open("http://localhost:8080/small.txt") => # #19 OpenURI, Tempfile and StringIO irb 15KB 12Kb

Slide 35

Slide 35 text

>> OpenURI::Buffer::StringMax => 10240 ! >> OpenURI::Buffer.send :remove_const, 'StringMax' => 10240 ! >> OpenURI::Buffer.const_set 'StringMax', 0 => 0 #19 OpenURI, Tempfile and StringIO irb

Slide 36

Slide 36 text

>> require 'open-uri' ! >> big = open("http://localhost:8080/big.txt") => # ! >> small = open("http://localhost:8080/small.txt") => # #19 OpenURI, Tempfile and StringIO irb

Slide 37

Slide 37 text

#20 Singleton Module >> OneAndOnly.instance === OneAndOnly.instance => true ! >> OneAndOnly.new NoMethodError: private method `new' called for OneAndOnly:Class irb require 'singleton' class OneAndOnly include Singleton end http://www.ruby-doc.org/stdlib-2.1.1/libdoc/singleton/rdoc/Singleton.html

Slide 38

Slide 38 text

>> mq = MyQueue.new => # ! >> mq.enq(1) => [1] ! >> mq.enq(2) => [1, 2] ! >> mq.size => 2 ! >> mq.deq => 1 #21 Forwardable Module irb class MyQueue extend Forwardable ! def_delegator :@q, :push , :enq def_delegator :@q, :shift, :deq ! def_delegators :@q, :[], :size ! def initialize @q = [] end end http://www.ruby-doc.org/stdlib-2.1.1/libdoc/forwardable/rdoc/Forwardable.html

Slide 39

Slide 39 text

#22 Bundler Jobs $> time bundle install 78.55s user 21.97s system 17% cpu 9:20.32 total ! $> time bundle install -j4 83.05s user 23.84s system 54% cpu 3:16.18 total shell http://bundler.io/v1.5/whats_new.html

Slide 40

Slide 40 text

#23 Bundler Jobs Config $> cores=`sysctl -n hw.ncpu` $> bundle config --global jobs $((cores)) ! $> cat ~/.bundle/config —- BUNDLE_JOBS: ‘4’ shell http://bundler.io/v1.5/whats_new.html

Slide 41

Slide 41 text

#24 Bundler Commands $> bundle outdated # List installed gems with newer versions available ! $> bundle console # Opens an IRB session with the Gemfile pre-loaded shell http://bundler.io/v1.6/commands.html

Slide 42

Slide 42 text

Rails Tips

Slide 43

Slide 43 text

class AddNameToProducts < ActiveRecord::Migration def change add_column :products, :name, :string add_index :products, :name end end Migration Syntax #25 https://github.com/rails/rails/blob/master/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb $> rails generate migration create_product AddNameToProducts name:string:index shell

Slide 44

Slide 44 text

class AddCategoryIdToProducts < ActiveRecord::Migration def change add_reference :products, :category_id, index: true end end Migration Syntax #26 https://github.com/rails/rails/blob/master/activerecord/lib/rails/generators/active_record/migration/migration_generator.rb $> rails generate migration create_product AddCategoryIdToProducts category_id:references shell

Slide 45

Slide 45 text

Sandboxed Console #27 $> rails console —-sandbox Any modifications you make will be rolled back on exit ! >> Product.all => # ! >> Product.create(name: “walkman") (0.0ms) SAVEPOINT active_record_1 SQL (1.7ms) INSERT INTO “products” ... (0.0ms) RELEASE SAVEPOINT active_record_1 => # ! >> exit (2.1ms) rollback transaction irb

Slide 46

Slide 46 text

Rake Notes #28 $> rake notes app/controllers/application_controller.rb: * [2] [TODO] remember to do this * [3] [FIXME] remember to fix this * [4] [OPTIMIZE] remember to optimize this irb class ApplicationController < ActionController::Base # TODO: remember to do this # FIXME: remember to fix this # OPTIMIZE: remember to optimize this end Uppercase Only! cd railsapp; rake -T

Slide 47

Slide 47 text

class UglyText def self.print puts <<-HERE I am not indented. But I am ugly on the inside. HERE end end Pretty Heredoc #29 >> UglyTest.print I am not indented. But I am ugly on the inside. irb

Slide 48

Slide 48 text

class NiceText def self.print puts <<-HERE.strip_heredoc I am not indented. And I look good on the inside. HERE end end Pretty Heredoc #29 >> NiceTest.print I am not indented. And I look good on the inside. irb

Slide 49

Slide 49 text

Question? #30 require 'active_support' ! class Winston cattr_writer :emotion def self.is ActiveSupport::StringInquirer.new(@@emotion) end end >> Winston.emotion = "happy" >> Winston.is.happy? => true irb

Slide 50

Slide 50 text

Sean Xie Dr. Khoo Chong Yee Teo Yinquan Teo Hui Ming Karthik T Credits

Slide 51

Slide 51 text

Thank You @winstonyw