2011-04-13 32 views
3

在Ruby中,我想選擇一個塊的默認對象。在Ruby中,有什麼方法可以完成Actionscript中的`with`操作?

在Actionscript中的一個例子是:

with (board) { 
    length = 66; 
    width = 19; 
    fin_system = 'lockbox'; 
}

即相當於:

board.length = 66; 
board.width = 19; 
board.fin_system = 'lockbox';

這裏是ActionScript則聲明的文檔: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/statements.html#with

我怎樣才能做到這一點在Ruby中?

+0

爲什麼要使用?除了_eval_,_with_是ECMAScript(a.k.a. javascript和actionscript)中最糟糕的部分 – 2011-04-13 19:05:00

+0

@invisible bob,你爲什麼認爲'with'是壞的?只爲興趣 – fl00r 2011-04-13 19:14:24

+0

@invisible bob,最簡單/最快的答案是遵循DRY原則。重複鍵入'board.'不是乾的。 – 2011-04-13 21:50:56

回答

6
Hash.new.tap do |h| 
    h[:name] = "Mike" 
    h[:language] = "Ruby" 
end 
#=> {:name=>"Mike", :language=>"Ruby"} 

你可以試試Object#tap與Ruby 1.9。

所以你的情況:

board.tap do |b| 
    b.length = 66; 
    b.width = 19; 
    b.fin_system = "lockbox" 
end 
+0

謝謝!我以前沒見過'tap()'。我仍然想保存這兩個按鍵('b.')。我正在考慮創建一個'with(obj,hash)'函數,它允許使用board {:length => 66,:width => 19,:fin_system =>'lockbox'}',但這只是移動鍵入「:」,「>」和「,」。 – 2011-04-13 20:46:53

1

你不能做到恰好在Ruby中,因爲foo = bar總是會設置一個foo局部變量;它永遠不會調用foo=方法。建議您可以使用tap。

一個解決方案,以更大的設計的問題是使用流利的接口:

board.length(66).width(20) 

class Board 
    def length(amt) 
    @length = amt 
    self 
    end 

    def width(amt) 
    @width = amt 
    self 
    end 
end 

這是給你,如果這個模式適合您的使用情況來決定。實現它

3

一種方法是用instance_eval,這樣的:

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 

但在某些情況下,你必須使用self(與運營商和設置方法)。

+0

謝謝,這是一個不錯的解決方案。但是我認爲,像@MikeLewis所描述的那樣,使用Ruby的原生'tap'更加優雅,可以節省擊鍵次數,並且...本地化。 – 2011-04-13 20:52:44

相關問題