4 ms·
A quick tips when creating block DSLs in Ruby: def search(&blk) if blk.arity == 1 blk.call(self) else self.instance_eval(&blk)
by judofyr 16y ago
A quick tips when creating block DSLs in Ruby:
def search(&blk)
if blk.arity == 1
blk.call(self)
else
self.instance_eval(&blk)
end
end
# Then the user can decide what he want to use:
Foo.search { bar }
Foo.search { |s| s.bar }
- troels 16y agoSo, the first invocation is similar to calling `Foo.search(&:bar)`, right?
- judofyr 16y agoYeah, but the whole point is really repeating local variables vs capturing self: # This wouldn't work because it binds the block to Foo, and the @bar # would lookup inside Foo instead of the proper context: Foo.search { bar == @bar } # This works fine though: Foo.search { |s| s.bar == @bar } Besides, if you're setting accessor, it can get a little weird: # Explicit and nice: Foo.search { |s| s.foo = 123 } # This actually sets a local variable: Foo.search { foo = 123 } # In order to fix it, we're back to the explicit one: Foo.search { self.foo = 123 } There is no silver bullet here, and I believe the best way is to provide both techniques and let the user decide.
- Vitaly 16y agoactually the second. &:bar is equivalent to {|x| x.bar}