In Ruby, I would like to select a default object for a block.
An example in Actionscript is:
with (board) {
length = 66;
width = 19;
fin_system = 'lockbox';
}
Which is equivalent to:
board.length = 66;
board.width = 19;
board.fin_system = 'lockbox';
Here is the documentation for this statement in Actionscript:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/statements.html#with
How can I accomplish this in Ruby?
Hash.new.tap do |h|
h[:name] = "Mike"
h[:language] = "Ruby"
end
#=> {:name=>"Mike", :language=>"Ruby"}
You could try Object#tap with Ruby 1.9.
So in your case:
board.tap do |b|
b.length = 66;
b.width = 19;
b.fin_system = "lockbox"
end
One way to implement it is with instance_eval
, like that:
def with(obj, &blk)
obj.instance_eval(&blk)
end
a = "abc"
with a do
self << 'b'
gsub!('b', 'd')
upcase!
end
puts a #=> ADCD
with board do
self.length = 66
self.width = 19
self.fin_system = 'lockbox'
end
But in some cases you have to use self
(with operators and setting methods).
You can't accomplish that exactly in Ruby because foo = bar
will always set a foo
local variable; it will never call a foo=
method. You can use tap as suggested.
One solution to the larger design question would be to use a fluent interface:
board.length(66).width(20)
class Board
def length(amt)
@length = amt
self
end
def width(amt)
@width = amt
self
end
end
It's up to you to decide if this pattern suits your use case.