【问题标题】:Understanding Ruby symbol as method call [duplicate]将Ruby符号理解为方法调用[重复]
【发布时间】:2013-01-22 02:05:13
【问题描述】:
class A
   def test
       "Test from instance"
   end
   class << self
       def test
           "Test from class"
       end
    end
end

p A.send(:test)    # "Test from class"
p A.new.method(:test).call  # "Test from instance"

这里的符号按预期工作,但在这里:

s="test"
s1=:s
p s1   # :s

为什么:s会打印在这里??我不明白背后的原因。 谁能帮我解释一下?

【问题讨论】:

    标签: ruby ruby-1.9


    【解决方案1】:

    符号是一种轻量级的字符串(尽管它们不是字符串)。 send()method() 方法可以采用字符串或符号;一个在内部工作中转换为另一个(不确定是哪个),然后 ruby​​ 执行具有匹配名称的方法。因此A.send(:text) 等价于A.text()。如果你有一个名为methodName = :text 的变量,你可以使用A.send(methodName),但不能使用A.methodName()

    符号不是变量,因此您不能为符号赋值。在您的示例中,符号 :s 与变量 s 无关(尽管它们具有相同的“名称”,但在其前面加上冒号使其成为符号而不是变量)。您正在为变量s 分配一个字符串值,但告诉它打印符号:s,它确实如此。

    【讨论】:

    • 这是一个答案(他不情愿地说)
    【解决方案2】:

    来自https://stackoverflow.com/a/1255362/509710

    p foo 确实 puts foo.inspect,即它打印inspect 的值而不是to_s,这更适合调试(因为您可以例如区分1"1""2\b1",在没有检查的情况下打印时不能这样做)。

    【讨论】:

    • 嘿,我现在明白了……我太傻了,我不知道 p 和 puts 之间的区别。谢谢
    【解决方案3】:

    您将 s1 的值设置为 :s,那么您为什么希望它返回任何不同的值呢?

    如果您查看 Object 类的 ruby​​ API,您会看到 Object#sendObject#method 都将符号作为参数,因此上面的示例也完全可以预期。

    【讨论】:

      【解决方案4】:
      s="test"
      s1=:s
      p :s.object_id  #137448
      p s.object_id   #77489950
      p s1.object_id  #137448
      

      我现在明白了。我正在分配一个符号,但期待一个字符串。

      【讨论】:

        【解决方案5】:

        符号只是一种特殊的类似字符串的值,运行时处理它比普通字符串更有效。而已。它们不是方法或变量或类似的东西。

        当您执行A.send(:test) 时,您所做的只是说“嘿,A,调用名为 'test' 的方法”。您不是发送方法本身,而是发送名称; send 内部的逻辑负责查找要调用的实际方法。

        当您使用A.new.method(:test) 请求方法时,也会出现同样的情况。您传递给method 的只是名称“test”,而不是使用该名称定义的方法。由method 使用名称并找到 实际方法以便它可以返回它,这就是你正在执行call 的返回值 - 一个 Method 对象。你不能在像:test 这样的符号上使用call,因为它只是一个名字。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-06
          • 2011-09-11
          • 2020-09-06
          • 2015-10-06
          • 2010-12-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多