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 在这里打印?我不明白它背后的原因。 有人可以帮我解释一下吗?
答案 0 :(得分:15)
符号是一种轻量级字符串(尽管它们不是字符串)。 send()
和method()
方法可以采用字符串或符号;一个在内部工作中转换为另一个(不确定是哪个)然后ruby执行具有匹配名称的方法。因此A.send(:text)
相当于A.text()
。如果您有一个名为methodName = :text
的变量,则可以A.send(methodName)
而不是A.methodName()
。
符号不是变量,因此您无法为符号指定值。在您的示例中,符号:s
与变量s
无关(尽管它们具有相同的“名称”,在它前面加上冒号使其成为符号而不是变量)。您正在为变量s
指定一个字符串值,但要告诉它打印符号:s
,它就是这样。
答案 1 :(得分:3)
来自https://stackoverflow.com/a/1255362/509710:
p foo
确实放foo.inspect
,即打印inspect
而不是to_s
的值,这更适合调试(因为你可以告诉它们之间的区别) 1
,"1"
和"2\b1"
,在未经检查的情况下打印时无法进行此操作。
答案 2 :(得分:2)
您将s1的值设置为:s,那么为什么您希望它返回任何不同的内容?
如果您查看Object类的ruby API,您会看到Object#send和Object#method都将符号作为参数,因此最上面的示例也是完全可以预期的。
答案 3 :(得分:2)
s="test"
s1=:s
p :s.object_id #137448
p s.object_id #77489950
p s1.object_id #137448
我现在明白了。我正在分配一个符号,但期待一个字符串。
答案 4 :(得分:1)
符号只是一种特殊的字符串,对于运行时来说更有效。而已。它们不是方法或变量或类似的东西。
当你执行A.send(:test)
时,你所做的就是说“嘿,A,调用名为'test'的方法”。你没有发送方法本身,只是名称;它是send
内部的逻辑,它负责查找要调用的实际方法。
当您要求使用A.new.method(:test)
的方法时,同样如此。您传递给method
的所有内容都是名称“test”,而不是定义为“test”的方法。最多method
使用名称,查找实际方法,以便它可以返回它,并且它是返回值 - 一个Method对象 - 您正在执行call
on 。您不能对call
这样的符号执行:test
,因为它只是一个名称。