아래 코드의 수퍼 클래스가 주어지면 모든 하위 클래스에 인스턴스 변수가 있기를 원합니다.
아래 코드는이를 수행하지만 가능한 모든 하위 클래스에 대해 해당 변수를 제대로 초기화하지 못합니다.
내 슈퍼 클래스의 고유 클래스를 열었습니다. 다음은 코드입니다 ( rubyfiddle 에도 있음 ).
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'
가능한 모든 하위 항목을 초기화하고 싶습니다. 처음 두 개의 풋에서만 SomeSuperClass.variable
초기화됩니다. 가능한 모든 하위 클래스에 대해이 변수를 초기화하는 방법을 모르겠습니다. 어떤 아이디어?
내가 찾은 가장 좋은 해결책은 다음과 같이 접근자를 재정 의하여 변수를 지연 초기화하는 것입니다.
class SomeSuperClass
def self.variable
@variable ||= 'Hi'
end
end
동기 :
주어진 클래스의 모든 하위 클래스가 필요합니다.이를 Vigilant라고 부르고 직접 하위 클래스에서 발생하는 몇 가지 일을 모니터링 할 수 있습니다. 이 정보는 클래스에 저장되므로 각각에 대해 다른 상태를 갖습니다.
두 클래스 A <B가 동일한 변수를 수정하므로 클래스 변수를 사용할 수 없습니다. 하위 클래스에 직접 액세스 할 수도 없으므로 Vigilant의 모든 하위 클래스에 하위 클래스에 대한 정보를 저장하고 검색 할 수있는 기능을 제공 할 방법이 필요했습니다.
고유 클래스를 여는 접근자를 정의함으로써 다음과 같이 말할 수 있습니다.
A.singleton_class.instance_eval { attr_accessor :x }
메서드 (접근 자)가 수퍼 클래스 고유 클래스에 추가되어 조회에서 찾을 수 있으므로 모든 서브 클래스 B class B < A; end
는 이제를 수행 B.x
할 수 있습니다.
첫 번째 예는 Bx가 Ax와 다르다는 것을 보여줍니다.
자, 제가 정말로 이해하지 못하는 것은 x가 어디에 있는지입니다. 접근자가 아닌 변수. 내가 할 경우 B.instance_variables
그것을 보여줍니다 []
B.singleton_class.instance_variables와 같은,
모든 하위 클래스가 단일 클래스 / 고유 클래스에 변수를 갖기를 원합니다.
죄송합니다. 여기서하는 일이 아닙니다.
puts SomeSuperClass.variable # => 'This only works for the superclass'
puts SubClass.variable # => '
왜 그 글을
SomeSuperClass.variable
의사 코드와 동일합니다.
SomeSuperClassSingletonClass.variable
또는 실제 코드 :
SomeSuperClass.singleton_class.variable
클래스와 싱글 톤 클래스는 두 개의 다른 클래스입니다.
또한이 코드 :
class << self
attr_accessor :variable
@variable = ': )' # This does't seem to have any effect
end
이 코드와 같은 방식으로 @variable에 대한 접근자를 만들지 않습니다.
class Dog
attr_accessor :x
@x = 'hello'
end
puts Dog.x
... 해당 @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
이러한 메서드는 모든 정의 외부에 정의 된 클래스 인스턴스 변수 @x 와는 아무 관련이 없습니다 . @ 변수는 그 순간에 self가되는 어떤 객체에 대해서도 조회 (또는 설정)됩니다. 이러한 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
들어 보겠습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다