Определение нового класса через метод с блоком

У меня есть функция, которая определяет и возвращает новый класс с некоторыми предварительно созданными методами. Например:

def define_class(name, options={}, &block)
  klass = Class.new(Class) do

    def say_hello
      puts "Hello!"
    end

    def say_goodbye
      puts "Adios!"
    end
  end

  parent_class.const_set(form_class, klass)
  klass
end

Так, например, это работает:

define_class("testing").new.say_hello   #=> "Hello!"

Но я хотел бы иметь возможность передавать пользовательские методы через блок, который затем будет добавлен в мой класс, например, так:

define_class "testing" do
  # ... custom methods
end

Так, что это будет работать:

klass = define_class "testing" do
  def interject
    puts "Excuse me?"
  end
end
klass.new.interject #=> "Excuse me?"

Я не могу понять, как заставить это работать хотя; Я пробовал instance_eval, class_eval и yield, и ни один из них не дает желаемого результата.

1 ответ

Решение

Попробуйте просто:

def define_class(name, options={}, &block)
  klass = Class.new(&block)

  parent_class.const_set(form_class, klass)
  klass
end

Если вы хотите вызвать блок и свой собственный блок, вы должны использовать class_eval:

def define_class(name, options={}, &block)
  klass = Class.new do

    def say_hello
      puts "Hello!"
    end

    def say_goodbye
      puts "Adios!"
    end

    class_eval(&block)
  end

  parent_class.const_set(form_class, klass)
  klass
end
Другие вопросы по тегам