Во сколько способов можно добавить методы к объекту ruby? - PullRequest
5 голосов
/ 13 июня 2011

Когда дело доходит до самоанализа во время выполнения и генерации динамического кода, я не думаю, что у ruby ​​есть какие-либо конкуренты, за исключением, возможно, некоторых диалектов lisp. На днях я выполнял некоторые упражнения с кодом для изучения динамических возможностей ruby ​​и начал задумываться о способах добавления методов к существующим объектам. Вот 3 способа, о которых я мог подумать:

obj = Object.new

# add a method directly
def obj.new_method
  ...
end

# add a method indirectly with the singleton class
class << obj
  def new_method
    ...
  end
end

# add a method by opening up the class
obj.class.class_eval do
  def new_method
    ...
  end
end

Это только вершина айсберга, потому что я до сих пор не исследовал различные комбинации instance_eval, module_eval и define_method. Есть ли онлайн / оффлайн ресурс, где я могу узнать больше о таких динамических трюках?

Ответы [ 3 ]

4 голосов
/ 13 июня 2011

Метапрограммирование Ruby , похоже, хороший ресурс.(И, оттуда связаны, Книга Рубина .)

3 голосов
/ 13 июня 2011

Если obj имеет суперкласс, вы можете добавить методы к obj из суперкласса, используя define_method (API) , как вы упомянули. Если вы когда-нибудь посмотрите на исходный код Rails, вы заметите, что они делают это совсем немного.

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

def method_missing(name, *args)
  string_name = name.to_s
  return super unless string_name =~ /^expected_\w+/
  # otherwise do something as if you have a method called expected_name
end

Добавление этого к вашему классу позволит ему отвечать на любой вызов метода, который выглядит как

@instance.expected_something
2 голосов
/ 14 июня 2011

Мне нравится книга Ruby метапрограммирования , которая издается издателями книги кирки.

...