2012-01-14 3 views

답변

3

Ruby 용 C 확장을 작성하는 경우 실제로 누군가가 설정할 때마다 세터 훅을 트리거하는 전역 변수를 만들 수 있습니다.

하지만 C를 써야하기 때문에 그렇게하고 싶지는 않을 것입니다. 관리하기가 어려울 수 있습니다.

더 나은 전략은 변수를 읽고 적절한 방법으로 설정하도록하는 것입니다. 그런 다음 setter 메서드가 호출되면 원하는 모든 작업을 수행 할 수 있습니다. 다음은 객체 내부에 변수를 캡슐화하는 예제입니다.

class Foo 
    def bar=(v) 
    @bar = v 
    # do some stuff 
    end 

    def bar 
    @bar 
    end 
end 

마찬가지로 변수를 객체 대신 모듈 또는 클래스에 캡슐화 할 수 있습니다.

+0

+1. 당신이 작성한 C 확장 모듈의 예를 가리킬 수있는 기회는 무엇입니까? – Swanand

+0

예, https://github.com/ruby/ruby/blob/trunk/README.EXT에서'rb_define_hooked_variable'을 확인하십시오. –

1

머리말 : 이것은 해결책이 아닙니다. (pst는 이미 작성했으나 없음) 특수한 상황에서 도움이 될 수 있습니다.

내 첫번째 생각은 솔루션을 얻을 수 freeze를 사용하는 것이 었습니다 : 지금

a = "aa" 
a.freeze 
a << 'b' #can't modify frozen string (RuntimeError) 

우리가 freeze를 재정의해야합니다 및 변수의 값이 변경 될 때 우리는 힌트를 얻을 :

module FreezeWarning 
    def freeze 
    puts "#{self}: I am changed" 
    end 
end 

a = "aa" 
a.extend(FreezeWarning) 
a.freeze 
a << 'b' #aa: I am changed 

먼저 문제를 : There is no way to get the variable name.

당신은

module FreezeWarning 
    def change_warning(name) 
    @varname = name 
    self.freeze 
    end 
    def freeze 
    puts "<#{@varname}> (#{self}): I am changed" 
    end 
end 

a = "aa" 
a.extend(FreezeWarning) 
a.change_warning('a') 
a << 'b' #<a> (aa): I am changed 

그러나 더 큰 문제 (당신은 당신의 자신의 변수 식별, 그것은 안됩니다 이름을 정의 할 수 있습니다) 추가 변수와 함께이 문제를 해결 할 수 가

: 이것은 단지 값의 변화,하지와 함께 작동 새 과제 :

a = 5 
a.freeze 
a = 4 
p a # -> 4 

그래서 매우 제한된 '해결책'입니다.

+0

아이디어를 제공해 주셔서 감사합니다. – sawa

관련 문제