将Ruby符号理解为方法调用


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??我不明白背后的原因。有人能为我解释一下吗?

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

符号不是变量,因此不能为符号指定值。在您的示例中,符号:s与变量s无关(尽管它们有相同的"名称",但在其前面加一个冒号会使其成为符号而不是变量(。您为变量s分配了一个字符串值,但告诉它打印符号:s,它确实这样做了。

符号只是一种特殊的字符串类值,对于运行时来说,它比常规字符串更有效。就是这样。它们不是方法、变量或诸如此类的东西。

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

当您要求使用A.new.method(:test)的方法时,也会发生同样的情况。您传递给CCD_ 15的只是名称";测试";,而不是使用该名称定义的方法。由method使用名称,找到实际方法,以便它可以返回它,而您正在对其执行call的返回值-method对象。您不能对像:test这样的Symbol执行call,因为它只是一个名称。

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

p foo确实放置了foo.inspect,即它打印inspect的值,而不是to_s的值,这更适合调试(因为你可以分辨出1"1""2b1"之间的区别,而在没有检查的情况下打印时无法分辨(。

s="test"
s1=:s
p :s.object_id  #137448
p s.object_id   #77489950
p s1.object_id  #137448

我现在已经明白了。我指定了一个符号,但期望得到一个字符串。

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

如果您查看Object类的ruby API,您将看到Object#send和Object#方法都将符号作为参数,因此顶部的示例也是完全预期的。

最新更新