2012-02-16 68 views

回答

3

構建CLR對象時沒有設置屬性的內置方式,因爲它不是Ruby自身的特性。不過,儘管Python不支持這個,IronPython does support it by allowing named parameters to be supplied to constructors。由於Ruby不支持命名參數,因此我們不希望強制實施一個命名參數模式,不管是作爲最後一個參數的Hash還是針對構造對象的instance_eval塊,或者其他人都想出的東西。這就是說,實現對象初始化器的兩種策略都可以在純Ruby中編寫,而IronRuby中沒有任何特殊的支持。我將描述上面列出的兩個,但可以隨意嘗試,如果它們不是您正在尋找的語法。

假設下面的CLR類(C#編寫):

namespace TestLib { 
    public class TestObj1 { 
    public string Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    } 
} 

你可以想象初始化與傳遞給構造塊屬性:

testobj = TestObj1.new do 
    self.prop1 = "Prop1 Value" 
    self.prop2 = "Prop2 Value" 
end 

這裏是你如何可以覆蓋TestObj1.new方法來支持:

class TestObj1 
    def self.new(*args, &block) 
    obj = super(*args) 
    obj.instance_eval &block 
    obj 
    end 
end 

由於這個a通過eval來阻止新創建的對象,您可以在該塊內執行任何Ruby代碼。在Ruby中創建DSL和更自然的API時,這種模式非常流行。

或者,如果你喜歡使用Ruby在方法的參數寬鬆Hash語法:

testobj = TestObj1.new :prop1 => "Prop1 value", :prop2 => "Prop2 value" 

那麼這就是你怎麼可以覆蓋.new方法:

class TestObj1 
    def self.new(*args) 
    last_arg = args[-1] 
    if last_arg.kind_of?(Hash) 
     first_args = args[0..-2] 
     obj = super(*first_args) 
     last_arg.each do |prop, val| 
     obj.send("#{prop}=", val) 
     end 
     return obj 
    end 
    super(*args) 
    end 
end 

Hash選項肯定是一個位更復雜,但性能更高一些(因爲它避免了eval),並且是Ruby中暴露命名參數的更常見模式。

相關問題