2012-02-16 65 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中暴露命名参数的更常见模式。

相关问题