我正在使用IronRuby在我的應用程序中執行一些腳本。有沒有辦法在IronRuby中設置類似於C#對象初始值設定語法的屬性?
我有很多需要創建和執行的命令(CLR對象),但大多數命令需要在它們上設置屬性,我想避免必須將命令分配給變量,以便我可以設置屬性。
有沒有辦法像C#對象那樣做initializer syntax?
我正在使用IronRuby在我的應用程序中執行一些腳本。有沒有辦法在IronRuby中設置類似於C#對象初始值設定語法的屬性?
我有很多需要創建和執行的命令(CLR對象),但大多數命令需要在它們上設置屬性,我想避免必須將命令分配給變量,以便我可以設置屬性。
有沒有辦法像C#對象那樣做initializer syntax?
構建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中暴露命名參數的更常見模式。