12

这个让我夜不能寐有一段时间了。

class Foo
  def bar
    'bar'
  end

  # What the hell is going on here?!?
  alias :baz :bar
end

Foo.new.baz #=> 'bar'

为什么alias将 2 个符号作为参数,但没有逗号分隔它们?在任何其他上下文中,这似乎都不是任何形式的有效语法。事实上,如果你确实使用了逗号,它实际上会引发语法错误。

alias :bar, :baz
# syntax error, unexpected ','

但是,如果我尝试以相同的方式将 2 个符号传递给我自己的方法,它也会爆炸:

def somemethod(*args)
  :whatever
end
somemethod :a :b
# syntax error, unexpected ':', expecting $end
  1. 那么,为什么aliasget 方法使用了没有其他方法可以使用的语法呢?
  2. 是否可以在任何其他上下文中使用此语法?
  3. 当语言中没有其他东西以这种方式工作时,使用这种奇怪的语法怪癖有什么好处?我认为这种语言不一致没有明显的好处。
4

2 回答 2

18

之所以alias有效是因为它是一个 Ruby 关键字,类似于class,def等。它不是一个方法。

alias关键字不需要逗号,因为 Ruby 设计者决定不需要逗号。关键字本质上是在解释器中硬编码的。

alias当您需要确定别名发生在解析时而不是运行时时,这是有充分理由的。

alias关键字可能令人困惑或令人惊讶。对于典型的开发,我认为最好使用 Ruby 方法Module#alias_method,它使用逗号并在运行时工作。

这是一篇关于aliasand的好博文alias_method

这是因为aliasis 一个关键字并且它是词法范围的。这意味着它被视为读取源代码时self的值。self相反,alias_method视为self在运行时确定的值。

总的来说,我的建议是使用alias_method. 由于 alias_method是在类中定义的方法,Module它可以在以后被覆盖,并提供更大的灵活性。

于 2012-11-22T00:30:14.737 回答
7

它不是一种方法,那些也不是论据。alias是 Ruby 中为数不多的关键字之一(请在此处查看所有关键字!)。它也困扰着我,所以我切换到alias_method(并且还有其他论点)。

于 2012-11-22T00:31:11.507 回答