ScopeGates в рубине - PullRequest
       5

ScopeGates в рубине

1 голос
/ 11 августа 2010

Я читаю Метапрограммирование в рубиновой книге. В этой книге, когда я читал о scopegates, был показан следующий код

my_var = "Success"

MyClass = Class.new do
  puts "#{my_var} in the class definition"

  define_method :my_method do
    puts "#{my_var} in the method"
  end
end

MyClass.new.my_method

=>Success in the class definition
  Success in the method

Теперь, когда я делаю выполнить в следующем, я получаю сообщение об ошибке неопределенного метода my_method MyClass.new MyClass: 0x00000100936a30

MyClass.my_method
NoMethodError: undefined method `my_method' for MyClass:Class
from (irb):11
from /usr/local/bin/irb:12:in `<main>'

Почему my_method создается, когда он вызывается как MyClass.new.my_method, а не MyClass.my_method?

1 Ответ

1 голос
/ 11 августа 2010

Метод define_method добавляет метод экземпляра в класс. Когда вы вызываете define_method в своем анонимном классе, ваш метод добавляется как метод экземпляра. Чтобы добавить его как метод класса, вы должны добавить его в метакласс.

Самый простой способ сделать это с помощью синтаксиса class << self.

MyClass = Class.new do
  class << self
    define_method(:my_method) do
      puts "class method"
    end
  end
end

MyClass.my_method # => "class method"
...