开发者

In Ruby, is there a way to accomplish what `with` does in Actionscript?

开发者 https://www.devze.com 2023-02-24 05:11 出处:网络
In Ruby, I would like to select a default object for a block. An example in Actionscript is: with (board) {

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消