2012-03-04 3 views
0

데모 코드를 보면 :인스턴스에서 클래스 변수에 어떻게 액세스합니까?

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 액세스 할 수있는 방법을 instance.but에 특별한 방법을 바인딩입니까?

업데이트 : 감사합니다. Boris Strandjev, Ur 정말 좋은 사람입니다. 당신이 위에서 언급 한 바와 같이, 나는 코드가 더 같이 단순화해야한다고 생각 :

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

Boris Strandjev의 대답. 마지막 문장을 실행할 수 없습니다. – LeoShi

답변

2
이 변경

당신의 bound_method에 :

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

이 인스턴스 변수가 아닌 클래스입니다.

EDIT 귀하의 의견에 따라 귀하의 문제를 해결하지 못했습니다. 그래서 저는 많은 고대 루비 지식을 녹여 내야했습니다. 이걸 찾았습니다 thread.

기본적으로 bind
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 

당신이 좋아 한 번 인스턴스에서이 메소드를 호출 할 수 있습니다 :

그리고 나는 더 당신의 방법을 변경

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

그러나 인스턴스에 메서드를 추가하지 않습니다 . :define_method 않습니다. 바라기를 이것은 당신을 도울 것입니다.

+0

감사합니다.하지만 여전히 작동하지 않는 것 같습니다. – LeoShi

+0

당신은 내가 오류를 피하려고 노력하고 있었고 당신의 최종 목표를 무시한 것입니다. 나는 그것을 바로 잡으려고 노력할 것이다. –

+0

내가 잘못하지 않으면 Ok 해결책을 찾았습니다. 몇 초 안에 나타납니다 내 편집보기 –

관련 문제