将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
,因为它只是一个名字。