将Ruby符号理解为方法调用

时间:2013-02-06 18:45:21

标签: ruby ruby-1.9

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 在这里打印?我不明白它背后的原因。 有人可以帮我解释一下吗?

5 个答案:

答案 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#sendObject#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,因为它只是一个名称。