将 Ruby 符号理解为方法调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14736452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding Ruby symbol as method call
提问by sunny1304
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"
Here symbol works as expected, but here:
这里的符号按预期工作,但在这里:
s="test"
s1=:s
p s1 # :s
why :sis printed here?? I dont understand the reason behind it. Can anyone please explain for me ?
为什么:s打印在这里?我不明白这背后的原因。谁能为我解释一下?
回答by Reinstate Monica -- notmaynard
Symbols are sort of lightweight strings (though they are not strings). The send()and method()methods can take strings or symbols; one is converted to the other in the inner workings (not sure which) and then ruby executes the method with the matching name. Hence A.send(:text)is equivalent to A.text(). If you had a variable named methodName = :text, you could do A.send(methodName)but not A.methodName().
符号是一种轻量级的字符串(尽管它们不是字符串)。的send()和method()方法可以采取串或符号; 一个在内部工作中转换为另一个(不确定是哪个),然后 ruby 执行具有匹配名称的方法。因此A.send(:text)等价于A.text()。如果您有一个名为 的变量methodName = :text,则可以执行A.send(methodName)但不能执行A.methodName()。
Symbols are not variables, so you can't assign a value to a symbol. In your example, the symbol :sis unrelated to the variable s(despite the fact that they have the same "name", preceding it with a colon makes it a symbol instead of a variable). You're assigning a string value to the variable sbut telling it to print the symbol :s, which it does.
符号不是变量,因此您不能为符号赋值。在您的示例中,符号:s与变量无关s(尽管它们具有相同的“名称”,但在其前面加上冒号使其成为符号而不是变量)。您正在为变量分配一个字符串值,s但告诉它打印符号:s,它确实这样做了。
回答by TheDude
From https://stackoverflow.com/a/1255362/509710:
从https://stackoverflow.com/a/1255362/509710:
p foodoes puts foo.inspect, i.e. it prints the value of inspectinstead of to_s, which is more suitable for debugging (because you can e.g. tell the difference between 1, "1"and "2\b1", which you can't when printing without inspect).
p foo确实 puts foo.inspect,即它打印的值inspect而不是to_s,这更适合调试(因为您可以例如分辨1,"1"和之间的区别,而"2\b1"在不检查的情况下打印时则无法区分)。
回答by sunny1304
s="test"
s1=:s
p :s.object_id #137448
p s.object_id #77489950
p s1.object_id #137448
I have understand it now. I was assigning a symbol but expecting a string.
我现在明白了。我正在分配一个符号但期待一个字符串。
回答by DanSingerman
You set the value of s1 to be :s, so why would you expect it to return anything different?
您将 s1 的值设置为 :s,那么您为什么希望它返回任何不同的内容呢?
If you look at the ruby API for the Object class, you will see both Object#sendand Object#methodtake a symbol as a parameter, so the top example is also totally expected.
如果您查看 Object 类的 ruby API,您将看到Object#send和Object#method 都将符号作为参数,因此上面的示例也完全符合预期。
回答by Mark Reed
Symbols are just a special kind of string that's more efficient for the runtime to deal with. That's it. They aren't methods or variables or anything like that.
符号只是一种特殊的字符串,运行时可以更有效地处理它。就是这样。它们不是方法或变量或类似的东西。
When you do A.send(:test), all you are doing is saying "hey, A, call the method named 'test'". You aren't sending the method itself, just the name; it's the logic inside sendthat is responsible for looking up the actual method to call.
当你这样做时A.send(:test),你所做的就是说“嘿,A,调用名为'test'的方法”。您发送的不是方法本身,而是名称;内部逻辑send负责查找要调用的实际方法。
The same thing goes when you ask for method with A.new.method(:test). All you are passing to methodis the name "test", not the method defined as "test". It's up to methodto use the name and findthe actual method so it can return it, and it's that return value - a Method object - that you are doing callon. You can't do callon a Symbol like :test, because it's just a name.
当您使用 请求方法时,情况也是如此A.new.method(:test)。您传递的method只是名称“test”,而不是定义为“test”的方法。取决于method使用名称并找到实际的方法,以便它可以返回它,这就是您正在处理的返回值 - 一个 Method 对象call。你不能call在像 那样的符号上做:test,因为它只是一个名字。

