2014-10-03 3 views
1

아래 코드의 수퍼 클래스에서 모든 서브 클래스에 인스턴스 변수가 필요합니다.수퍼 클래스의 서브 클래스의 클래스 인스턴스 변수 초기화

아래의 코드는이를 수행하지만 가능한 모든 하위 클래스에 대해 해당 변수를 제대로 초기화하지 못합니다.

내 수퍼 클래스의 고유 클래스를 열었습니다. 내가 초기화 가능한 모든 sublcasses을하고 싶은

class SomeSuperClass 
    class << self 
    attr_accessor :variable 
    @variable = ':)' # This does't seem to have any effect 
    end 
    self.variable = 'This only works for the superclass' 
end 

class SubClass < SomeSuperClass; end 

puts SomeSuperClass.variable # => 'This only works for the superclass' 
puts SubClass.variable # => '' 

SomeSuperClass.variable = 'I am the superclass' 
SubClass.variable = 'I am the subclass' 

puts SomeSuperClass.variable # => 'I am the superclass' 
puts SubClass.variable # => 'I am the subclass' 

: 여기에 (도 rubyfiddle에서) 코드입니다. 처음 두 puts에서는 SomeSuperClass.variable 만 초기화됩니다. 모든 하위 클래스에 대해이 변수를 초기화하는 방법을 모르겠습니다. 어떤 아이디어?

내가 찾은 가장 좋은 해결책은 같이 접근을 무시하고 게으른 초기화 변수에있다 :

class SomeSuperClass 
    def self.variable 
    @variable ||= 'Hi' 
    end 
end 

동기 :

나는 주어진 클래스의 모든 서브 클래스가 필요합니다, Vigilant라고 부르면 직접 하위 클래스에서 일어나는 일을 모니터 할 수 있습니다. 이 정보는 클래스에 저장되므로 각각 정보가 다릅니다.

두 클래스 A < B가 동일한 변수를 수정하므로 클래스 변수를 사용할 수 없습니다. 서브 클래스에 직접 액세스 할 수 없기 때문에 경계 클래스의 모든 서브 클래스에 서브 클래스에 대한 정보를 저장하고 검색하는 기능이 필요했습니다. 고유치 클래스를 여는 접근을 정의함으로써

는 말할 수 : 방법 (접근)는 슈퍼 클래스의 고유 클래스에 추가 되었기 때문에

A.singleton_class.instance_eval { attr_accessor :x } 

모든 서브 클래스가 class B < A; end는 지금 B.x을 할 수있는 B, 및 따라서 조회에서 찾을 수 있습니다.

그리고 첫 번째 예는 B.x는 여기서 X는 내가 정말 이해 아니에요 것은 지금 A.x

에서

다르다는 것을 보여줍니다; 변수가 아니라 접근 자. 내가 B.instance_variables을 경우 내가 모든 서브 클래스가 싱글 톤 클래스/eigenclass에 변수를 갖고 싶어 B.singleton_class.instance_variables

+0

'puts '가있는 행은 도움이되지 않습니다. 모든. 당신은 그들로부터 어떤 결과를 얻습니까? – sawa

+0

문제는 완전히 명확하지 않습니다. 처음에는 변수를 공유하고 싶지 않다고 썼습니다. 그런 다음 나중에 변수를 공유하려는 것처럼 작성했습니다. 변수를 공유하고 싶은 부분과 공유하지 않으려는 부분은 무엇입니까? – sawa

+0

당신은 바로 @sawa입니다, 출력으로 편집하겠습니다. 어쨌든, 그 이유는 내가 rubyfiddle을 만들었습니다 – Logain

답변

2

와 같은, []을 보여줍니다.

SomeSuperClassSingletonClass.variable 
:

puts SomeSuperClass.variable # => 'This only works for the superclass' 
puts SubClass.variable # => ' 

가 왜

SomeSuperClass.variable 

를 작성하는 것은 의사 코드에 해당한다고 생각합니다 :

죄송합니다, 그건 당신이 여기에서 무엇을하고 있는지 아니다

또는 실제 코드 :

SomeSuperClass.singleton_class.variable 

클래스 및 그것의 싱글 톤 클래스는 두 개의 다른 클래스입니다. 또한

,이 코드 :

class Dog 
    attr_accessor :x 

    @x = 'hello' 
end 

puts Dog.x 

...이에 대한 접근을 생성하지 않습니다

class << self 
    attr_accessor :variable 
    @variable = ':)' # This does't seem to have any effect 
    end 

, 즉 @variable이 코드가하는 것과 같은 방식으로 접근을 만들지 않습니다 그 @x 변수 :

--output:-- 
undefined method `x' for Dog:Class (NoMethodError) 

무엇 attr_accessor() 수행은 이것이다 :

class Dog 
    def x 
    @x 
    end 

    def x=(val) 
    @x = val 
    end 

    #===== 

    @x = 'hello' 
end 

이러한 메서드는 모든 def 외부에서 정의 된 @x 클래스 인스턴스 변수 인스턴스 변수와 아무 관련이 없습니다. @variables는 그 순간에 어떤 객체가 자기 자신인지에 대해 조회 (또는 설정)됩니다. 그 def를 호출 할 수있는 유일한 객체는 Dog 클래스의 인스턴스이므로 x는 Dog 클래스가 아닌 Dog 인스턴스에서 조회 (또는 설정)됩니다.

또한 @x = 'hello' 행이 실행될 때 self는 Dog 클래스와 동일하므로 @x는 Dog 클래스에 연결됩니다.

싱글 톤 클래스에서 인스턴스 변수를 설정하는 유스 케이스가 없다고 생각합니다. 여기가 당신이하려고하는 것 같아 무엇 :

class SomeSuperClass 
    class << self 
    attr_accessor :variable 
    end 

    self.variable = 'hello' 

    def self.inherited(subclass) 
    subclass.singleton_class.instance_eval do 
     attr_accessor :variable 
    end 

    subclass.variable = "Hi" 
    end 

end 

class SubClass < SomeSuperClass 
end 

puts SomeSuperClass.variable 
puts SubClass.variable 


--output:-- 
hello 
Hi 

그 코드가 class instance variables로 알려져 있습니다 무엇을 만듭니다. singleton class instance variables에 대한 사용 사례가 있다고 생각한다면 들으십시오.

+0

좋아요! instance_eval에 대한 필요성이없는 것 같습니다. – Logain

+0

나는 아마 자신을 올바르게 표현하지 않았습니다. 미안합니다. 내가 원래 클래스 변수를 원하지 않는다고 말한 원래의 질문에 대한 잔재였습니다. 내가 말한 의미는 "모든 하위 클래스에 변수와 접근 자 동작이 있어야합니다"입니다.내가 올바르게 이해한다면, 나는 eigenclass를 수정함으로써 그 행동을 추가한다. 나는 여전히 instance_eval의 필요성을 이해하지 못한다. 왜냐하면 그것 없이는 잘 작동하기 때문에 그렇다. – Logain

+0

@AlvarezAriel, 문서화되지는 않았지만, 분명히 singleton_class는 씬 뒤에서 instance_eval()을 사용하는 블록을 허용하기 때문에 명시 적으로 작성할 필요가 없습니다. 그러나 경험 많은 프로그래머라면 그것에 대해 궁금해 할 것입니다. instance_eval()에 대한 명시가 명백합니다. 특히 그 행위가 문서화되지 않은 경우에는 더욱 그렇습니다. – 7stud

관련 문제