Ruby发送没有符号

时间:2010-06-23 16:46:41

标签: ruby send

是否可以不向对象发送任何内容?

让我详细说明一下。例如,我可以这样:

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

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

上述调用不起作用,因为nil不是符号。所以解决方案是:

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

但是我不太喜欢这个。还有其他办法吗?

3 个答案:

答案 0 :(得分:5)

我不知道任何返回self而没有接受任何参数的方法(但我可能会忽略某些东西),但是没有理由你不能将一个方法打包到你正在使用的类中:< / p>

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 :(得分: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 :(得分:2)

我可能会误解某些东西,但我认为这个问题试图做一些没有意义的事情。

在Ruby中,向对象发送消息意味着要求该对象以某种方式响应所请求的消息(在这种情况下使用符号指定)。消息是我们通常称为方法调用的消息。在此示例中,“send”是发送给对象的消息,接收消息“send”的对象接受传递的参数(另一个方法的符号)并向自身(对象)发送与该方法对应的消息。通过了符号。

所以发送一个对象nil几乎等同于不发送任何对象 - 除了你已经实际上向对象发送了一条消息,只有一个没有任何内容。所以这个对象不可避免地被混淆了它应该做什么,因为它被告知什么都不做。如果有人要求你什么都不做,你也不会感到困惑吗?:)

所以转向你的具体问题:

要重新解释你的问题(要清楚我是否理解它),我想你在问:是否有可能链接一系列调用,其中链中的一个调用仅在变量(调用方法)时发生通过发送消息)是非零的吗?

对于通用解决方案,这可能更好吗?

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

否则,要真正回答你的问题(现在确实有意义,但可能会让事情变得更复杂),你可以把它放在你的课堂上:

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

或者你可以这样做:

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

这会导致每个对象接受nil(并且悄悄地什么都不做)发送。

此解决方案将引发警告[原文如此]:

  

警告:重新定义“发送”可能会导致严重问题

你可以通过重定向$ stderr来抑制这个警告,但它不是线程安全的(Matz说,来自谷歌的简短搜索)。