루비에는 구문의 관련 응용 프로그램이 있습니까 : 클래스 << self… End
문제
class << self
attr_accessor :n, :totalX, :totalY
end
위의 구문은 클래스 인스턴스 변수를 정의하는 데 사용됩니다. 그러나 구문이 무엇을 의미하는지 생각할 때, 그것은 나에게 의미가 없기 때문에,이 유형의 구문이 다른 유형의 정의에 사용되는지 궁금합니다. 여기서 혼란의 요점은 다음과 같습니다.
class << self
Append 연산자는 일반적으로 "왼쪽의 객체에 오른쪽을 추가"를 의미합니다. 그러나이 블록의 맥락에서, "이 블록의 내용을 인스턴스가 아닌 클래스 인스턴스의 정의에 넣는 것"에 어떻게 추가됩니까?
같은 이유로 나는 한 컨텍스트 클래스에서 << self가 클래스 인스턴스 변수를 정의 할 수 있지만 다른 컨트롤 변수를 정의 할 수있는 이유에 대해 혼란스러워합니다.
class Point
# Instance methods go here
class << self
# Class methods go here
end
end
해결책
루비에서는 기존 클래스를 다시 열고 방법을 추가 할 수 있습니다. 즉, 당신은 다음과 같이 말할 수 있습니다.
class Foo
def bob
return "hello from bob"
end
end
이 방법은 내부 사전 (아마도 인스턴스 변수)에 어딘가에 저장됩니다. Foo
-클래스 (단지 인스턴스 일뿐입니다 Class
-클래스 가지다 인스턴스 변수)
그러나 놀라운 것은 인스턴스 기존 객체의
foo = Foo.new
foo2 = Foo.new
def foo.fred
return "I am fred"
end
foo.fred #=> "I am fred"
foo2.fred #=> NoMethodError
하지만 이 방법은 실제로 어디에 저장되어 있습니까??
루비가 무대 뒤에서 새로운 클래스를 만듭니다 (때로는 싱글 톤 클래스, 메타 클라스 또는 고유 한) 상속 상속인에 삽입됩니다 ~ 사이 그만큼 Foo
-클래스와 인스턴스.
따라서 상속 관계는 다음과 같습니다.
foo < (eigenclass of foo) < Foo < Class
(foo.superclass라고 말하면 싱글 톤 클래스가 표시되지 않습니다)
그만큼 class << X
-syntax는이 특별 수업에 도달하여 직접 조작 할 수있는 방법입니다. 다음 코드 블록은 정확히 동일합니다.
def foo.bar
return "xy"
end
# is exactly the same as
class << foo
def bar
return "xy"
end
end
그래서 사이의 유사성 class Foo < Bar
그리고 class << Foo
우연이 아니며, 둘 다에서 상속이 진행되고 있습니다.
에 대해 생각하다 class << X
"X의 메타 클라스를 열어"로
루비에서 기억해야 할 것은 수업 자체가 단지 대상이라는 것입니다. (수업 인스턴스 Class
) 그러니 당신이 말하면 :
class Foo
class << self
def k
return "x"
end
end
end
(self
묶여 있습니다 Foo
이 코드 블록에서) k
이다 인스턴스 방법 고유의 Foo
,이를 수업 방법으로 만듭니다 Foo
이 모든 것이 더 명확하게 설명되어 있습니다 곡예물의 수업에 관한 장 (웹 버전에는 불행히도 다이어그램이 포함되어 있지 않습니다) 및 _whys 메타 클래스를 명확하게보고 있습니다
다른 팁
클래스는 모든 액세서 및 인스턴스 변수를 포함한 회원 사전을 포함한다고 생각하십시오. 클래스에 "자체"에 "부록"을 "클래스 멤버 사전에 추가"라고 말할 때.
그래도 표기법을 부여 할 것입니다.
실제로 "Append"연산자의 관점에서 생각하는 것은 혼란 스럽습니다. 그것을 보는 더 좋은 방법은 class Foo
클래스 Foo를 열어줍니다. class << self
현재 '자기'객체의 고유 성분을 열어줍니다. 자체에 국한되지 않습니다 - 모든 객체 막대의 경우 클래스 << bar를 말할 수 있습니다.
class A
def hello
print "hello world"
end
end
a = A.new
b = A.new
class << a
def goodbye
print "goodbye cruel world"
end
end
a.hello
b.hello
a.goodbye
b.goodbye