将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执行具有匹配名称的方法。 因此A.send(:text)等同于A.text() 。 如果您有一个名为methodName = :text的变量,则可以执行A.send(methodName)但不能使用A.methodName()

符号不是变量,因此您无法为符号指定值。 在您的示例中,符号:s与变量s无关(尽管它们具有相同的“名称”,在它前面加上冒号使其成为符号而不是变量)。 您正在为变量s指定一个字符串值,但要告诉它打印符号:s ,它会这样做。

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

p foo确实放了foo.inspect ,即它打印的是inspect而不是to_s的值,这更适合调试(因为你可以告诉1"1""2\b1"之间的区别,你可以’ t打印时不检查)。

你将s1的值设置为:s,那么为什么你会期望它返回任何不同的东西呢?

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

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

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

符号只是一种特殊的字符串,对于运行时来说更有效。 而已。 它们不是方法或变量或类似的东西。

当你做A.send(:test) ,你所做的只是说“嘿,A,调用名为’test’的方法”。 你没有发送方法本身,只是名称; 这是send内部的逻辑,它负责查找要调用的实际方法。

当你用A.new.method(:test)要求方法时,情况A.new.method(:test) 。 您传递给method所有内容都是名称“test”,而不是定义为“test”的方法。 这取决于使用名称并找到实际方法的方法,以便它可以返回它,并且它是返回值 – 一个Method对象 – 您正在call它。 你无法call符号如:test ,因为它只是一个名字。