2012-11-24 5 views
0

내 자신의 라이브러리를 개발하는 과정에서 일반적인 숙어를 이해하기 위해 Github에서 다양한 Ruby 라이브러리를 읽었습니다. 내가 참조한 한 라이브러리 (found here)는 "첨부되지 않은 메소드 보내기"를 활용합니다. 여기 코드는 : 나는 루비의 전송 방법에 관한 온라인으로 찾을 수 있습니다Ruby에서 연결되지 않은 send 메소드를 사용하는 적절한 방법은 무엇입니까?

module AngellistApi 
    class API 

     attr_accessor *Configuration::VALID_OPTIONS_KEYS 

     # Creates a new API 
     def initialize(options={}) 
      options = AngellistApi.options.merge(options) 
      Configuration::VALID_OPTIONS_KEYS.each do |key| 
      send("#{key}=", options[key]) 
      end 
     end 
    end 
end 

모든 문서는, 문자열이나 기호를 통해 객체의 메소드를 호출하는 방법으로 그것을 설명합니다. 그러나 모든 예제에는 객체에 send 메소드가 있습니다. 예 :

object.send(:method_name, argument1) 

객체에 첨부되지 않은 경우 어떻게됩니까? 이 경우 호출 된 클래스의 메서드를 호출하고 있습니까? 누군가 나를 위해이 코드를 설명 할 수 있습니까? :)

답변

1

인스턴스 메소드 내부에서 발생하므로 여기에 내포 된 객체는 self입니다.

# create a new object, assigning "foo = bar" given that 
# foo is in VALID_OPTIONS_KEYS 
object = AngellistApi::API.new({:foo => 'bar'}) 

# this would essentially do the same thing again 
object.send("foo=", "bar") 

# (which is equivalent to) 
object.foo = bar 
+0

아 아아 ... 전화 키의 구성 요소를 놓쳤습니다 ... 훌륭합니다 ... 감사합니다! –

+0

빠른 질문 하나 ... 그 변수가 그 시점에서 인스턴스 변수가된다고 가정합니다. –

+0

이 경우 yes는 클래스가 유효한 옵션 키를 기반으로 한 attr_accessors를 정의하기 때문입니다. 예제에서와 같이': foo => 'bar''를 전달하고'foo'가 유효한 키라면 객체에'@ foo' 인스턴스 변수가 생깁니다. 'foo'가 유효한 키가 아니라면, 객체를 초기화하려고 할 때'NoMethodError'를 얻습니다. – numbers1311407

2

는 "무소속"그것은 명시 수신기없이 메서드 호출, 그래서 대신은 self암시 수신기를 사용, 올바른 용어가 아닙니다. 따라서 send(:foo) (암시 적 리시버)은 self.send(:foo) (명시 적 리시버)과 동일합니다. 이것은 send에 고유하지 않으며 모든 메소드 호출에 해당됩니다.

이 등가성이 유일하지 않은 유일한 시간은 명시 적 수신자로 개인 메소드를 호출 할 수 없으므로 호출 된 메소드가 개인용 인 경우입니다 (실제로는 Ruby에서 개인용의 정의입니다).

0

일반적으로 루비에서는 명시 적 수신자없이 메소드가 호출 될 때 암시 적 수신자는 self입니다. self은 때로는 미끄 럽게 될 수 있습니다. - self이 다양한 컨텍스트에 있다는 것을 이해하는 것이 Ruby 숙달의 길에서 중요하고 계몽적인 단계입니다. :-) Yehuda Katz는 주제에 a nice article을 가지고 있으며 거기에는 many others이 있습니다.

나는 the Pry alternative REPL가 탐험에 도움이 될 수 있다고 생각합니다. AngelList API lib 디렉토리가로드 샘플 세션 :

여기
[1] pry(main)> cd AngellistApi::API 
[2] pry(AngellistApi::API):2> self 
=> AngellistApi::API 
[3] pry(AngellistApi::API):2> ls 
Object.methods: yaml_tag 
AngellistApi::API#methods: access_token access_token= adapter adapter= connection_options connection_options= endpoint endpoint= gateway gateway= proxy proxy= user_agent user_agent= 
locals: _ _dir_ _ex_ _file_ _in_ _out_ _pry_ binding_impl_method 

당신이 attr_accessor *Configuration::VALID_OPTIONS_KEYS의 결과로 정의 된 접근을 볼 수 있습니다.

+0

물론, 꾸밈없는'initialize' 메쏘드에서'self'가 초기화 될 객체 일 가능성이 큽니다. – numbers1311407

+0

예, 고맙습니다. 아마도 질문에 답하기위한 가장 중요한 세부 사항 일 것이며 생략했습니다! 문제의 보석에 대한 공헌자로서 나는이 예제가 메타 프로그래밍의 상당히 심각한 남용이라고 생각한다. 접근자를 열거하면 각 설정 옵션이 실제로 무엇인지 문서화 할 수있는 좋은 기회가 될 것이다. 보석은 원래 당시 트위터 보석 인 IIRC에서 크게 찢어졌습니다. – ches

관련 문제