Skip to content

Instantly share code, notes, and snippets.

@bkempner
Created October 21, 2011 19:38
Show Gist options
  • Save bkempner/1304733 to your computer and use it in GitHub Desktop.
Save bkempner/1304733 to your computer and use it in GitHub Desktop.
class Foo
def initialize(options)
@bar = options.fetch(:bar, nil)
@baz = options.fetch(:baz, nil)
end
end
def Foo(options)
Foo.new(options)
end
ruby-1.9.2-p290 :028 > f = Foo bar: 'chuck', baz: 'testa'
=> #<Foo:0x007ffdd407fec0 @foo="chuck", @bar="testa">
@sahilshah-rr
Copy link

Is it in some way better than @foo = options[:foo] || nil or for that matter @foo = options[:foo] || <expression>?

@bkempner
Copy link
Author

@sashah87 they are pretty much equivalent, however you can pass a block using fetch:

options.fetch(:bar) { def wtf; puts 'wtf'; end; wtf }

=> 'wtf'

options[:bar] || { def wtf; puts 'wtf'; end; wtf }

=> SyntaxError: (pry):4: syntax error, unexpected ';', expecting tASSOC

However, you can pretty much do the same thing using conditional as well:

options[:bar] || lambda { def wtf; puts 'wtf'; end; wtf }.call

So many the take away is, if you passing a block, fetch is more concise, if your just setting a default value conditions are more concise.

However, the really cool part of this snippet is using the class constant to represent both the class and a method.

@sahilshah-rr
Copy link

Yup! That it is!

@bkempner
Copy link
Author

@sashah87

Also, with a condition you could have problems if the value of options[:foo] is false, then it will always set default value. With fetch it will only set default value if the key is missing.

Also, another trick I just learned:

h = Hash.new { 'foo' }
h[:foo] #=> 'foo'
h[:bar] #=> 'foo'
h[:baz] = 'baz' #=> 'baz'

@sahilshah-rr
Copy link

Ahhh. That's an important catch. Cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment