为什么方法定义会返回符号?

4
当你定义一个方法时,它会返回一个与方法同名的符号。这样做有什么意义吗?还是只是为了验证你创建了它?
就像这样:
def something
   ...
end
# => :something
4个回答

11
IRb总是显示最后一个被评估表达式的值调用inspect方法的结果。无论该表达式是文字表达式、条件表达式、消息发送、类定义表达式还是方法定义表达式都不重要。
在Ruby中,所有东西都返回一个值,即所有东西都是表达式,在Ruby中没有语句这样的东西。
过去,方法定义表达式的返回值未定义。大多数Ruby实现只从方法定义表达式中返回nil,但例如Rubinius返回所定义方法的CompiledMethod对象。
在Ruby 2.1中,方法定义表达式的返回值被标准化为与方法名称对应的Symbol。这使您可以将方法定义表达式用作期望方法名称作为参数的方法的参数。
一些例子:
# Before Ruby 2.0:
def foo; end
private :foo

# After Ruby 2.0:
private def foo; end # similar for `protected`, `public`, `module_function`

# Before Ruby 2.0:
def map; end
alias_method :collect, :map

# After Ruby 2.0:
alias_method :collect, def map; end

就个人而言,我更希望方法定义表达式能够评估为对应该方法的UnboundMethod对象,而像publicprivateprotectedalias_methodmodule_function等方法也应该修改为除SymbolString外还能接受UnboundMethod


2
我认为是2.1,而不是2.0。 - sawa
我最初同意你关于UnboundMethod对象的想法,但是后来我考虑了一下attr_...方法和alias关键字,它们在某种程度上类似,但不能被设计为接受UnboundMethod对象。如果其中一些方法接受UnboundMethod对象,而另一些方法只接受符号,那么这将会很令人困惑。毕竟,符号看起来是引用方法名称最可靠的方式。 - sawa
@JörgWMittag alias_method 是 Ruby 中的吗? :-) - Arup Rakshit
@JörgWMittag 嗯...我以为它是在Rails中..谢谢 - Arup Rakshit
记得在您的示例中更新版本。我建议使用“<2.1”和“>= 2.1”,而不是模糊的“before & after”。 - Kelvin

5
这位提出此建议的人意在将其用于以下场景:
private def foo
  ...
end
protected def bar
  ...
end

publicprivateprotected这样的方法需要符号作为参数。这样做的目的是利用这种语法。


这个有文档记录吗? - Stefan
1
@Stefan 我在 RDoc 中找不到任何相关信息。他们应该写一些关于这个的内容。 - sawa
@sawa 这个语法不够优美,之前的更加漂亮。 :-( - Arup Rakshit
@sawa 我的意思是这个语法 - Arup Rakshit
@sawa 我被说服了。我的经验很少,所以我之前并不知道。现在我被说服了。谢谢。 - Arup Rakshit

2
所有的方法定义在 Ruby >=2.1 中都返回符号(不仅仅是在 IRB 中)。
例如:
class Foo
  p def bar; end
end
# => prints :bar

为什么这很有意思?

你可能已经注意到,有许多方法,特别是类级别的方法,将另一个方法的符号名称作为参数。你可能熟悉Rails控制器中的before_filter。由于方法定义返回符号,你有可能这样做:

class MyController < ApplicationController
  before_filter def my_filter
     # do stuff
  end
end

1
puts 替换为 p 将会打印出 :bar - Stefan

0

IRB 遵循 Ruby 标准“方法返回最后执行语句的结果”。想象一下以下代码:

def a
  def b
    # do stuff
  end
end

执行此代码的结果是什么?如下:

a
# => :b
a.class
# => Symbol < Object

话虽如此,IRB执行该方法定义并返回/打印其结果。这明显是一个Symbol实例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接