为什么方法定义会返回符号?
定义方法时,它返回与方法同名的符号。 这有什么意义吗? 或者它只是作为您创建它的validation?
像这样:
def something ... end # => :something
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
对象,并且应该修改public
, private
, protected
, alias_method
, module_function
等方法以接受除了Symbol
之外的UnboundMethod
。和String
s。
提出这个的人想到了这样的用法:
private def foo ... end protected def bar ... end
public
, private
, protected
将符号作为参数。 关键是要使用这种语法。
所有方法defs返回Ruby> = 2.1中的符号(不仅仅是IRB中的符号)。
例如:
class Foo p def bar; end end # => prints :bar
为什么这很有趣?
您可能已经注意到有许多方法,特别是类级方法,它们将另一个方法的符号化名称作为参数。 您可能熟悉Rails控制器中的before_filter
。 由于方法defs返回符号,您可能会这样做:
class MyController < ApplicationController before_filter def my_filter # do stuff end end
IRB
遵守ruby标准“从方法返回最后执行语句的结果。”想象一下代码:
def a def b # do stuff end end
执行此代码的结果是什么? 它跟随:
a # => :b a.class # => Symbol < Object
也就是说,IRB执行方法定义并返回/打印出它的结果。 显然,这是一个Symbol
实例。