루비 보내기 대 __send__
나는 개념을 이해 some_instance.send
하지만 왜 이것을 두 가지 방법으로 부를 수 있는지 알아 내려고 노력 중입니다. Ruby Koans는 동일한 작업을 수행하는 다양한 방법을 제공하는 것 이상의 이유가 있음을 암시합니다. 사용 예는 다음과 같습니다.
class Foo
def bar?
true
end
end
foo = Foo.new
foo.send(:bar?)
foo.__send__(:bar?)
누구든지 이것에 대해 알고 있습니까?
일부 클래스 (예 : 표준 라이브러리의 소켓 클래스) send
는 관련이없는 자체 메서드를 정의합니다 Object#send
. 따라서 어떤 클래스의 객체로 작업 __send__
하려면 안전한면에 있어야합니다.
이제 그 질문이 남았습니다. 왜 그런지 send
아닌지 __send__
. 단지이 있다면 __send__
이름이 send
혼동없이 다른 클래스에 의해 사용될 수 있습니다. 그 이유는 즉 send
최초의 존재 만 나중에는 이름이 실현되었다 send
그래서,도 유용하게 다른 상황에서 사용될 수있다 __send__
(무슨 일이 있었 같은 일이이 추가되었다 id
및 object_id
방법에 의해).
당신이 경우 정말 필요 send
정상적으로 할 것처럼 행동하려면 사용해야 __send__
은 (는 안된다) 오버라이드 (override) 할 수 없기 때문에. 사용 __send__
은 조작하는 클래스가 어떤 메소드를 정의하는지 모르는 경우 메타 프로그래밍에 특히 유용합니다. 재정의했을 수 있습니다 send
.
손목 시계:
class Foo
def bar?
true
end
def send(*args)
false
end
end
foo = Foo.new
foo.send(:bar?)
# => false
foo.__send__(:bar?)
# => true
을 무시하면 __send__
, Ruby는 경고를냅니다 :
경고 :`__send__ '를 재정의하면 심각한 문제가 발생할 수 있습니다
재정의하는 send
것이 유용한 경우 는 메시지 전달, 소켓 클래스 등과 같이 해당 이름이 적절한 경우 가 있습니다.
__send__
실수로 덮어 쓸 수 없도록 존재합니다.
왜 send
존재 하는지에 관해서는 : 나는 다른 사람을 위해 말할 수는 없지만 object.send(:method_name, *parameters)
보다 더 멋지게 보입니다 object.__send__(:method_name, *parameters)
. 따라서 사용할 필요 가 send
없으면 사용 합니다.__send__
그렇다에서 무엇을 다른 사람이 이미 당신에게 무엇을 말하는 아래로 비등 send
과 __send__
같은 방법으로 두 개의 별칭, 세 번째에 관심이있을 수 있습니다, somwhat 다른 가능성이다 public_send
. 예:
A, B, C = Module.new, Module.new, Module.new
B.include A #=> error -- private method
B.send :include, A #=> bypasses the method's privacy
C.public_send :include, A #=> does not bypass privacy
업데이트 : 루비 2.1, 이후 Module#include
및 Module#extend
공공 될 방법, 위의 예는 더 이상 작동하지 않을 것 때문에.
send __send__
, 및 public_send 의 주요 차이점은 다음과 같습니다.
- send
__send__
는 기술적으로 Object의 메소드를 호출하는 데 사용되는 것과 동일하지만 가장 큰 차이점은 경고없이 send 메소드를 재정의 할 수 있으며 재정의 할 때__send__
경고 메시지가 있다는 것입니다
경고 : 재정의
__send__
하면 심각한 문제가 발생할 수 있습니다
이는 사용될 컨텍스트를 알 수 없을 때 특히 gem이나 라이브러리에서 충돌을 피하기 위해 항상 __send__
send 대신 사용하십시오 .
- send (또는
__send__
)와 public_send 의 차이점은 send__send__
는 개체의 개인 메서드를 호출 / 호출 할 수 있고 public_send는 호출 할 수 없다는 것입니다.
class Foo
def __send__(*args, &block)
"__send__"
end
def send(*args)
"send"
end
def bar
"bar"
end
private
def private_bar
"private_bar"
end
end
Foo.new.bar #=> "bar"
Foo.new.private_bar #=> NoMethodError(private method 'private_bar' called for #Foo)
Foo.new.send(:bar) #=> "send"
Foo.new.__send__(:bar) #=> "__send__"
Foo.new.public_send(:bar) #=> "bar"
Foo.new.send(:private_bar) #=> "send"
Foo.new.__send__(:private_bar) #=> "__send__"
Foo.new.public_send(:private_bar) #=> NoMethodError(private method 'private_bar' called for #Foo)
At the end try to use public_send to avoid direct call to private method instead of using __send__ or send.
참고URL : https://stackoverflow.com/questions/4658269/ruby-send-vs-send
'Programming' 카테고리의 다른 글
G ++를 사용하여 여러 .cpp 및 .h 파일 컴파일 (0) | 2020.06.15 |
---|---|
ssh : 호스트 'hostname'의 신뢰성을 설정할 수 없습니다 (0) | 2020.06.15 |
PHP에 배열 키가 있는지 확인하는 것이 더 빠르고 더 좋은 방법은 무엇입니까? (0) | 2020.06.15 |
Intellij에서 다른 하위 버전 분기로 전환하려면 어떻게합니까? (0) | 2020.06.15 |
java.lang.IllegalArgumentException :보기가 창 관리자에 첨부되지 않았습니다 (0) | 2020.06.15 |