2016-09-12 3 views
3

무작위 질문은 여기에 있습니다. 나는 이것에 대한 용어가 있는지 모르겠다. 그러나 명시 적 리시버없이 메소드를 정의 할 때 어떤 클래스가 메소드를 얻는지를 어떻게 알 수 있을까? 그게 무엇이든간에 self이 무엇입니까?Ruby 명시 적 수신기가 없을 때 어떤 클래스가 메소드를 얻나요?

self은 클래스 정의의 컨텍스트에서 정의되는 클래스이며 암시 적 수신기로 정의 된 메서드는 항상 클래스에 바인딩됩니다.

, 나는 'sub_method가'뿐만 아니라 외부 클래스에 넣어지고 있음을 인스턴스 메서드 내부의 방법을 정의하는 경우 : 최고 수준 범위에서 또한

[12] pry(main)> class A 
[12] pry(main)* def my_method 
[12] pry(main)*  puts self 
[12] pry(main)*  def sub_method 
[12] pry(main)*  puts self 
[12] pry(main)*  end 
[12] pry(main)* end 
[12] pry(main)* end 
=> :my_method 
[13] pry(main)> a = A.new 
=> #<A:0x007fa588181d40> 
[14] pry(main)> a.my_method 
#<A:0x007fa588181d40> 
=> :sub_method 
[15] pry(main)> a.sub_method 
#<A:0x007fa588181d40> 
=> nil 
[16] pry(main)> A.instance_methods(false) 
=> [:my_method, :sub_method] 

, selfmain입니다입니다 Object 클래스의 인스턴스하지만 방법이없는 나는 내가 본 방법 다른 싱글 방법을 기반으로 예상 된 것입니다 main의 단일 클래스로, Object에가 추가됩니다 정의 된 작업 :

여기에 무슨 일이 벌어지고 있는지, 규칙이 있습니까? 아니면 알아야 할 몇 가지 사례가 있습니까?

답변

4

Ruby에는 세 가지 암시 적 컨텍스트가 있습니다.

가장 잘 알려진 것은 self, 현재 개체 및 기본 수신기입니다.

잘 알려진 두 번째는 상수 조회에 사용되는 범위입니다. 대체로 말하자면 상수 조회는 "어휘 적으로 바깥 쪽이며 상속에 의해 상향"이지만 많은 뉘앙스가 있습니다. Ruby 관리자는이 컨텍스트를 cref이라고합니다.

당신이 묻는 것은 the third context, sometimes called the default definee입니다. 일반적으로 기본 정의는에 가장 가까운 어휘로 둘러싸는 입니다. 그러나 최상단에서 기본 정의는 실제로 Object입니다 (기본값 가시성private 임).instance_eval은 메시지의 수신자로 self을 변경하고 은 기본 정의 (수신자의 싱글 톤 클래스)으로 변경합니다. class_eval은 수신자에게 모두 변경됩니다.

+1

그리고 당신이 그것을 찾기 시작하기 전에 : 그 블로그 포스트의 저자는 불행하게도, 세 번째 암시 적 컨텍스트에 대해 언급 한 적이 없다. –

+1

그리고 그녀를 모르는 사람들을 위해 : Yugui는 Ruby 1.9의 릴리스 관리자였으며 Ruby 디자인, 개발, 유지 관리 및 릴리스 프로세스에서 많은 개선을 담당했습니다. 때로는 Ruby 1.8의 나쁜 옛날을 잊어 버립니다. –

6

사람들이 "정의 된 모든 방법에 대한 대상 컨텍스트"와 같이 용어와 "수신자"가 일반적으로 의미하는 "메시지 수신자"와 같이 "수신자"를 혼란스럽게 생각합니다.

메서드 내에서 def을 호출하는 것은 구문에 허용되지만 스타일 측면에서는 정통합니다. 이 작업을 수행하는 Ruby의 방식은 해당 메소드의 위치를 ​​제어 할 수있는 곳인 define_method을 사용하고 있습니다. def을 메소드 정의의 간단한 방법으로 생각해보십시오. 그러나 컨텍스트가 약간 미끄러 우면. 클래스 컨텍스트에서 호출되면 인스턴스 메서드를 정의합니다. 인스턴스 메소드 내에서 호출되면 다른 인스턴스 메소드를 정의합니다.

모듈에서 해당 메소드를 래핑하는 것이 나중에 include 또는 extend으로 표시 될 수 있습니다.

최상위 범위에서 메서드를 정의하면 main에 있으며 이는 해당 메서드를 보편적으로 사용할 수 있음을 의미합니다. 이를 수행하는 가장 좋은 방법은 객체를 객체에 강제로 배치하는 것입니다. 이런 맥락에서 메소드를 정의하는 것이 서둘러 지저분해질 수 있기 때문에 사소한 프로그램 이외에는 권장되지 않습니다.

+0

그래, 내가 수신기를 잘못 말하고있는 것 같아. 그곳에있는 모든 것들이 추악하고 결코 이루어져서는 안된다는 것을 안다. 나는 아무것도 지정되지 않았을 때 메소드가 속한 기본 클래스가 정의 된 곳인 'self'와 관련이 있는지 여부를 이해하려고 시도했다. – anthonygiuliano

+0

메소드 호출을 할 때 컨텍스트는 대개 예측 가능합니다. JavaScript에서는'this'가 Ruby에서 변경되지 않습니다. 'def'를 사용할 때 메소드가 어디에서 사용되는지에 대한 몇 가지 간단한 규칙이 있지만'main' 또는'class' 또는'module' 내부에서 직접 사용되도록 의도 된 것입니다. – tadman