2013-02-06 30 views
8
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" 

这里符号按预期工作,但在这里:了解Ruby的符号作为方法调用

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

为什么:■这里打印?我不明白它背后的原因。 任何人都可以为我解释一下吗?

回答

2

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

如果您看看Object类的ruby API,您会看到Object#sendObject#method都将一个符号作为参数,因此顶部示例也是完全可以预料的。

3

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

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

+0

嘿,我现在明白了......这真是愚蠢,我知道p和put之间的区别。谢谢 – sunny1304

14

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

符号不是变量,所以您不能将值分配给符号。在您的示例中,符号:s与变量s无关(尽管它们具有相同的“名称”,在它之前用冒号使其成为符号而不是变量)。您正在给变量s分配一个字符串值,但要让它打印它所做的符号:s

+0

这是一个答案(他连续说) – DanSingerman

0

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

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

当您要求A.new.method(:test)的方法时,也会发生同样的情况。您传递给method的所有名称都是“测试”的名称,而不是定义为“测试”的方法。这是由method使用名称和找到的实际方法,所以它可以返回它,它的返回值 - 一个方法对象 - 你在做call上。您不能在:test等符号上执行call,因为它只是一个名称。

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

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