Как использовать метапрограммирование Ruby для динамического создания класса с помощью метода initialize? - PullRequest
0 голосов
/ 13 сентября 2018

Вариант использования: чтение пар ключ / значение из файлов yaml и создание классов для каждого из них.Динамические классы должны иметь метод инициализации, который вызывает метод load_page_objects_with_globals для каждого файла yml.

Проблема: Метод инициализации не реализуется с каждым динамически создаваемым классом.

 def load_page_object_with_globals page_objects_file_name
    load_page_object_file(open("filepath/page_objects/#{page_objects_file_name}"))
    load_page_object_file(open("filepath/page_objects/global_page_object.yml"))
    puts page_objects_file_name
  end

  #dynamically creates methods based key/value pairs in yaml file
  def load_page_object_file(file)
    page_object = YAML.load(File.read(file))
    page_object.each do |k, v|
      self.class.__send__ :define_method, k do v end
    end
  end

  #
  def load_page_object_classes
    page_object_class_names = Array.new
    #camelizes the filenames into class name format
    Dir.glob("filepath/page_objects/*.yml").each do |item|
      filename = File.basename(item, ".*")
      filename = filename.dup.split(/[_-]/).map(&:capitalize).join("")
      page_object_class_names.push(filename)
    end
    puts page_object_class_names.inspect
    #PROBLEM CODE - dynamically create a class for each page object name and create initalize method
    page_object_class_names.each {
      |class_name|
      page_object_classes = Class.new(Object) do
        define_method(initialize) do
          load_page_object_with_globals(open("filepath/page_objects/#{class_name}.yml"))
        end
      end
      Class.const_set(class_name, page_object_classes)
      puts page_object_classes.inspect
    }
  end
  load_page_object_classes

1 Ответ

0 голосов
/ 14 сентября 2018

Как-то так у меня сработало:

require 'active_support/all'

def multiply_by(number1, number2)
  number1 * number2
end

hash = { foo: 1, bar: 2, baz: 3 }

hash.each do |k, v|
  klass_name = k.to_s.camelize
  klass = Class.new(Object) do
    define_method(:initialize) do |param|
      @test = multiply_by(v, param)
    end
  end
  Object.const_set(klass_name, klass)
end

puts Foo.new(1).inspect
puts Bar.new(2).inspect
puts Baz.new(3).inspect
...