2010-06-23 3 views
1

아무 것도 보내지 않을 수 있습니까?루비는 기호없이 보내기

자세히 설명해 드리겠습니다. 전무는 상징이 아니기 때문에

val = some_stack.include?(some_val) ? some_val : nil 

obj1.obj2.send(val).obj3.obj4 

위의 호출 wont't 작업 : 예를 들어 나는 이런 식으로 뭔가를 할 수있다. 해결책은 다음과 같습니다.

if val.nil? 
    obj1.obj2.obj3.obj4 
else 
    obj1.obj2.send(val).obj3.obj4 
end 

그러나 나는 이것을 좋아하지 않습니다. 다른 방법이 있습니까?

답변

5

내가 반환하는 모든 방법을 잘 모르는 것 같아요 self (아무 것도 간과 할 수도 있음)을 사용하지 않아도되지만 사용중인 수업에 Monkeypatch 할 수없는 이유는 없습니다.

irb(main)> class Object 
irb(main)> def ignore 
irb(main)>  self 
irb(main)> end 
irb(main)> end 
=> nil 
irb(main)> msg = nil 
=> nil 
irb(main)> 'hi'.send(msg || :ignore).upcase 
=> "HI" 
irb(main)> msg = :reverse 
=> :reverse 
irb(main)> 'hi'.send(msg || :ignore).upcase 
=> "IH" 
+1

Ruby 2.2부터는'Kernel # itself'을 사용할 수 있으므로 더 이상 패치 할 필요가 없습니다. – Aert

4

내장 방법이 없습니다. 당신은 다음 작업을 수행 할 수 있습니다 :

module Kernel 
    def __self__ 
    self 
    end 
end 

obj1.obj2.send(val || :__self__).obj3.obj4 

더 비밀 :

[:obj1, :obj2, val, :obj3, :obj4].compact.inject(self, :send) 
# (assuming that obj1 is a method call like obj2, ...) 

하지만 단순하게 유지하는 것이 좋습니다 것 :

intermediate = obj1.obj2 
intermediate = intermediate.some_val if some_stack.include?(some_val) 
intermediate.obj3.obj4 
2

나는 오해를하고 있을지 모르지만 나는이 질문이 의미가없는 것을하려고 시도하고 있다고 생각합니다.

Ruby에서 객체에 메시지를 보내는 것은 객체가 요청 된 메시지에 어떤 방식 으로든 응답하도록 요청하는 것을 의미합니다 (이 경우에는 심볼이 지정됨). 메시지는 우리가 일반적으로 메서드 호출이라고 부르는 것입니다. 이 예제에서 "send"는 객체에 전송 된 메시지이고 "send"메시지를 수신 한 객체는 전달 된 인수 (다른 메소드의 심볼)를 사용하여 해당 객체에 대한 메소드에 해당하는 메시지를 보냅니다. 통과 된 상징.

그래서 객체를 보내지 않는 것은 거의 객체를 보내지 않는 것과 같습니다. 단, 이 실제로 객체에 메시지를 보냈지 만 내용이없는 객체 만 보냈습니다. 따라서 객체는 필연적으로 수행해야 할 작업에 대해 혼란 스럽습니다. 아무 것도하지 말라는 것이기 때문입니다. 당신은 누군가가 당신이 아무것도하지 않는 요구하는 경우도 혼동하지 않을까요 :)

그래서 특정 질문에 켜 :

귀하의 질문에 (내가 알고있는 여부를 명확하게하는)을 바꿔하려면, 당신이 생각하는 묻습니다 : 체인에있는 호출 중 하나가 변수 (메시지를 보내는 방식으로 호출하는 메서드)가 nil이 아닌 경우에만 발생하는 일련의 호출을 연결할 수 있습니까?

아마도 이것은 일반적인 용도의 솔루션에 더 좋을까요?

def send(method, *args) 
    super if method 
end 

는 다른 방법으로이 작업을 수행 할 수 있습니다

obj2 = obj1.obj2 
obj2 = obj2.send(val) if val 
obj2.obj3.obj4 

그렇지 않으면, 실제로 귀하의 질문에 대답 (지금 이해 않지만, 일을 더 복잡하게 만들 수도 있습니다), 당신은 당신의 수업이 넣을 수 있습니다 :

그러면 모든 객체가 전송을 위해 아무 것도받지 않고 (아무 것도하지 않음) 전송하게됩니다.

경고 [원문] 도발 것이 솔루션 :

경고 :`를 재정의 당신은 $의 표준 오류 리디렉션하여이 경고를 억제 할 수

심각한 문제를 일으킬 수 있습니다 '를 보낼 수 있지만, 그것의를 threadsafe하지 않습니다 (Matz, 간단한 Google 검색에서 말합니다).

관련 문제