Есть ли способ установить свойства в Ironruby, похожий на синтаксис инициализатора объекта C#?

StackOverflow https://stackoverflow.com/questions/9304459

  •  25-10-2019
  •  | 
  •  

Вопрос

Я использую 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

Так как это на самом деле evalS Блок против недавно созданного объекта, вы можете выполнить любой код 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 для обнаружения названных параметров.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top