Как я могу получить доступ к переменной класса в экземпляре? - PullRequest
0 голосов
/ 04 марта 2012

посмотрите демонстрационный код:

class A
  def method_a
    puts "this is method_a"
  end
end

class B < A
  def self.hide_method name
    if instance_methods.include? name
      @hidden_mthod ||= {}
      @hidden_mthod[name] = instance_method name
      undef_method name
    end
  end

  def self.invoke_hidden_methods
    puts @hidden_mthod.inspect
  end

  def bound_method name
    self.class.class_variable_get(:@hidden_mthod)[name].bind(self)
  end
end

b = B.new
b.method_a
B.hide_method :method_a
B.invoke_hidden_methods

b.bound_method :method_a  **#error**

b.method_a **#error**

Что я хочу сделать, это привязать специальный метод к экземпляру. Но как я могу получить доступ к @hidden_method, который определен в классе с методом экземпляра?

ОБНОВЛЕНИЕ: Спасибо, Борис Странджев, Ура действительно хороший человек. как вы упомянули выше, я думаю, что код должен быть более упрощенным, как это:

def bound_method name
  method_body = self.class.instance_variable_get(:@hidden_method)[name]
  self.class.send :define_method, name, method_body
end

1 Ответ

2 голосов
/ 04 марта 2012

Измените bound_method на:

def bound_method name
    self.class.instance_variable_get(:@hidden_mthod)[name].bind(self)
end

Это переменная экземпляра, а не класс.

РЕДАКТИРОВАТЬ В соответствии с вашим комментарием я не решил вашу проблему. Поэтому мне пришлось стереть много древних рубиновых знаний. Я нашел эту тему .

А потом я изменил ваш метод дальше:

def bound_method name
  puts self.class.instance_variable_get(:@hidden_mthod)[name]
  metaclass = class << self; self; end
  metaclass.send(:define_method, name,
             self.class.instance_variable_get(:@hidden_mthod)[name])
end

В основном bind позволит вам вызывать этот метод для экземпляра один раз, например:

self.class.instance_variable_get(:@hidden_mthod)[name].bind(self).call()

Но не добавляет метод к экземпляру. :define_method делает. Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...