Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

CHRIS GAFFNEY @gaffneyc Collective Idea Harmony harmonyapp.com

Slide 3

Slide 3 text

Keyword Arguments Module#prepend Enumerable#lazy Refinements Bonus Round

Slide 4

Slide 4 text

Keyword Arguments Module#prepend Enumerable#lazy Refinements Bonus Round

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

VAROPTS def foo(headers: {}, **options) end foo(test: "not an argument") # headers = {} # options = { test: "not an argument" }

Slide 7

Slide 7 text

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"}

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Keyword Arguments Module#prepend Enumerable#lazy Refinements Bonus Round

Slide 10

Slide 10 text

MODULE#PREPEND class Foo < Object end Foo.ancestors # => [ Foo, Object, BasicObject ]

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Keyword Arguments Module#prepend Enumerable#lazy Refinements Bonus Round

Slide 18

Slide 18 text

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?) # :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

Slide 19

Slide 19 text

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]

Slide 20

Slide 20 text

Keyword Arguments Module#prepend Enumerable#lazy Refinements Bonus Round

Slide 21

Slide 21 text

BASIC USAGE

Slide 22

Slide 22 text

BASIC USAGE module Foo refine String do def hello "world" end end end

Slide 23

Slide 23 text

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"

Slide 24

Slide 24 text

Keyword Arguments Module#prepend Enumerable#lazy Refinements Bonus Round

Slide 25

Slide 25 text

#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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

# 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

Slide 28

Slide 28 text

# 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

Slide 29

Slide 29 text

# 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)

Slide 30

Slide 30 text

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 # # unset LANG LC_CTYPE LC_ALL File.open("send_test.rb", "r:utf-8") { |f| f.read }.encoding #

Slide 31

Slide 31 text

CHRIS GAFFNEY @gaffneyc Collective Idea Harmony harmonyapp.com