Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Intro to Ruby 2.0

Chris Gaffney
February 27, 2013

Intro to Ruby 2.0

An introduction to the cool new features in Ruby 2.0.

http://youtu.be/wjmt_a73tSk

Chris Gaffney

February 27, 2013
Tweet

More Decks by Chris Gaffney

Other Decks in Technology

Transcript

  1. BASIC USAGE # Common patterns def foo(options = {}) headers

    = options.delete(:headers) end def foo(options = {}) options[:headers] ||= {} end # With keyword arguments def foo(headers: {}) end foo # headers = {} foo(headers: { "Content-Type: text/html" }) # headers = { "Content-Type: text/html" } foo(test: "not an argument") # ArgumentError: unknown keyword: test foo("headers" => "Will a string work?") # ArgumentError: unknown keyword: headers
  2. VAROPTS def foo(headers: {}, **options) end foo(test: "not an argument")

    # headers = {} # options = { test: "not an argument" }
  3. ALL THE OPTIONS # required argument, varargs, keyword arguments, varopts

    def foo(required, *args, kw: nil, **options) end foo(5) foo(5, 6, 7, 8) foo(5, 6, 7, 8, kw: true) foo(5, 6, 7, 8, kw: true, test: "too true") # required = 5 # args = [ 6, 7, 8 ] # kw = true # options = { :test => "too true"}
  4. SUPER class Foo def awesome_method(keyword: "go") puts keyword end end

    class Bar < Foo def awesome_method(keyword: "bar") super end end Bar.new.awesome_method # => go # Keyword arguments are not automatically passed to super
  5. MODULE#PREPEND class Foo < Object include Bar include Baz end

    Foo.ancestors # => [ Foo, Bar, Baz, Object, BasicObject ]
  6. MODULE#PREPEND class Foo < Object include Bar include Baz prepend

    Buz end Foo.ancestors # => [ Buz, Foo, Bar, Baz, Object, BasicObject ]
  7. MODULE#PREPEND class Foo < Object include Bar include Baz prepend

    Buz prepend Bat end Foo.ancestors # => [ Bat, Buz, Foo, Bar, Baz, Object, BasicObject ]
  8. ALIAS METHOD CHAIN class Foo def bar puts "bar" end

    end # Standard pattern: reopen the class and alias_method_chain class Foo def bar_with_baz puts "baz" bar_without_baz end alias_method :bar_without_baz, :bar alias_method :bar, :bar_with_baz end Foo.new.bar # baz # bar
  9. USE PREPEND INSTEAD module Baz def bar puts "baz" super

    end end class Foo prepend Baz def bar puts "bar" end end # Or class_eval since prepend is private Foo.class_eval { prepend Baz } Foo.new.bar # baz # bar
  10. BASIC USAGE %w(1 2 3 4).map(&:to_i).select(&:even?) # [ 2, 4

    ] # Intermediary steps: # [ "1", "2", "3", "4" ] => [ 1, 2, 3, 4 ] => [ 2, 4 ] %w(1 2 3 4).inject([]) do |memo, val| val = val.to_i memo << val if val.even? memo end # [ 2, 4 ] %w(1 2 3 4).lazy.map(&:to_i).select(&:even?) # <Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: [...]>:map>:select> %w(1 2 3 4).lazy.map(&:to_i).select(&:even?).to_a # [ 2, 4 ] %w(1 2 3 4).lazy.map(&:to_i).select(&:even?).each { |v| puts v } # 2 # 4
  11. INFINITE / LARGE SETS (0..1_000_000_000).select(&:even?).take(10) # I don't know... it

    crashed my computer (0..1_000_000_000).lazy.select(&:even?).take(10).to_a # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
  12. BASIC USAGE module Foo refine String do def hello "world"

    end end end # Pretend this is in bar.rb require "foo" # Refinements currently have file scope using Foo class Bar def foo "".hello end end puts Bar.new.foo # => "world"
  13. #to_h # Hashes return themselves { foo: "bar" }.to_h #

    { :foo => "bar" } # Structs have a representation FooBar = Struct.new(:foo, :bar) FooBar.new("baz", "buz").to_h # => { :foo => "baz", :bar => "buz" } # Nil gives an empty hash nil.to_h # => {} # OpenStruct! OpenStruct.new(:foo => "bar").to_h # => { :foo => "bar" } # Be more permissive on what types of objects we can accept def foo(hash) if hash.respond_to?(:to_h) hash = hash.to_h else raise ArgumentError, "zomg I want a hash" end end
  14. # We alread have %w for strings strings = %w(test

    foo bar) # [ "test", "foo", "bar" ] %i / %I
  15. # We alread have %w for strings strings = %w(test

    foo bar) # [ "test", "foo", "bar" ] # Now we have %i for symbols symbols = %i(test foo bar) # [ :test, :foo, :bar ] %i / %I
  16. # We alread have %w for strings strings = %w(test

    foo bar) # [ "test", "foo", "bar" ] # Now we have %i for symbols symbols = %i(test foo bar) # [ :test, :foo, :bar ] # Or use %I if you need interpolation symbols = %I(test #{"foo"}) # [ :test, :foo ] %i / %I
  17. # In previous versions of ruby this line can be

    expensive: fork do 1 + 1 end # Ruby deployment is typically done with multiple processes. When each process # takes a big chunk of memory it's common to see: # Copy on Write makes fork calls cheaper because memory is only copied when it # is changed. # If one process takes 200Mb then 10 processes means 2Gb # Copy-on-Write can reduce that footprint significantly for subprocesses. Copy-on-Write (COW)
  18. ENCODING # unicode.rb puts "¿Cómo estás?" # 1.9 $ ruby

    unicode.rb unicode.rb:1: invalid multibyte char (US-ASCII) unicode.rb:1: invalid multibyte char (US-ASCII) # 2.0 $ ruby unicode.rb ¿Cómo estás? File.read("unicode.rb").encoding # <Encoding:ASCII> # unset LANG LC_CTYPE LC_ALL File.open("send_test.rb", "r:utf-8") { |f| f.read }.encoding # <Encoding:UTF-8>