문제

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top