如何在实例中访问类变量?

时间:2012-03-04 10:17:20

标签: ruby

查看演示代码:

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?

更新: 谢谢你,Boris Strandjev,你真是个好人。如上所述,我认为代码应该更加简化:

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

1 个答案:

答案 0 :(得分:2)

将您的bound_method更改为:

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

这是实例变量,而不是类。

编辑根据您的评论,我没有解决您的问题。所以我不得不摒弃许多古老的红宝石知识。我找到了thread

然后我进一步改变了你的方法:

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。希望这会对你有所帮助。