Есть ли способ установить свойства в Ironruby, похожий на синтаксис инициализатора объекта C#?
Вопрос
Я использую Ironruby, чтобы сделать сценарий в моем приложении.
У меня есть много команд (объекты CLR), которые мне нужно создать и выполнить, но большинству команд нуждаются свойства, установленные на них, и я хочу избежать необходимости назначать команду переменной, чтобы я мог установить свойства.
Есть ли способ сделать это как объект C# Синтаксис инициализатора?
Решение
Не существует встроенного способа установления свойств при построении объектов CLR, так как это не особенности самой Ruby. Однако, хотя Python это тоже не поддерживает, Ironpython поддерживает его, позволяя поставляться с названными параметрами для конструкторов. Анкет Поскольку Ruby не поддерживает названные параметры, мы не хотели обеспечить соблюдение именованного шаблона параметров, будь то Hash
как последний аргумент, или блок, который instance_eval
'D против строительного объекта или чего -то еще, что люди придумают.
При этом обе стратегии реализации инициализаторов объектов могут быть написаны в Pure 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
Так как это на самом деле eval
S Блок против недавно созданного объекта, вы можете выполнить любой код 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 для обнаружения названных параметров.