我应该使用alias还是alias_method?

我找到了一篇关于alias vs. alias_method的博客文章。正如那篇博客文章中给出的例子所示,我只是想在同一个类中将一个方法别名为另一个方法。我应该用哪一种?我总是看到alias被使用,但是有人告诉我alias_method更好。

别名的使用

class User


def full_name
puts "Johnnie Walker"
end


alias name full_name
end


User.new.name #=>Johnnie Walker

alias_method的使用

class User


def full_name
puts "Johnnie Walker"
end


alias_method :name, :full_name
end


User.new.name #=>Johnnie Walker

博客文章链接这里

146663 次浏览

如果需要,可以重新定义alias_method。(它在Module类中定义。)

alias的行为取决于它的作用域,有时是相当不可预测的。

结论:使用alias_method -它给你更多的灵活性。

用法:

def foo
"foo"
end


alias_method :baz, :foo

支持alias而不是alias_method的一点是,它的语义可以被rdoc识别,导致生成的文档中有整齐的交叉引用,而rdoc完全忽略alias_method

我认为有一个不成文的规则(有点像惯例),说使用'alias'只是为了注册一个方法名别名,这意味着如果你想给你的代码的用户一个具有多个名称的方法:

class Engine
def start
#code goes here
end
alias run start
end

如果你需要扩展你的代码,使用ruby元替代。

class Engine
def start
puts "start me"
end
end


Engine.new.start() # => start me


Engine.class_eval do
unless method_defined?(:run)
alias_method :run, :start
define_method(:start) do
puts "'before' extension"
run()
puts "'after' extension"
end
end
end


Engine.new.start
# => 'before' extension
# => start me
# => 'after' extension


Engine.new.run # => start me

在提出这个问题一年后,一篇关于这个主题的新文章出现了:

http://erniemiller.org/2014/10/23/in-defense-of-alias/ < a href = " http://erniemiller.org/2014/10/23/in-defense-of-alias/ " > < / >

似乎“这么多人,这么多人。”在前一篇文章中,作者鼓励使用alias_method,而后者建议使用alias

然而,在上面的博文和回答中,这些方法都有一个共同的概述:

  • 当你想将别名限制在定义的范围内时,使用alias
  • 使用alias_method允许继承类访问它

除了语法,主要的区别在于范围:

# scoping with alias_method
class User


def full_name
puts "Johnnie Walker"
end


def self.add_rename
alias_method :name, :full_name
end


end


class Developer < User
def full_name
puts "Geeky geek"
end
add_rename
end


Developer.new.name #=> 'Geeky geek'

在上面的例子中,方法“name”选择在“Developer”类中定义的方法“full_name”。现在让我们尝试alias

class User


def full_name
puts "Johnnie Walker"
end


def self.add_rename
alias name full_name
end
end


class Developer < User
def full_name
puts "Geeky geek"
end
add_rename
end


Developer.new.name #=> 'Johnnie Walker'

使用别名时,方法“name”不能选择Developer中定义的方法“full_name”。

这是因为alias是一个关键字,它是词法范围。这意味着它在读取源代码时将self作为self的值。相反,alias_methodself作为运行时确定的值。

来源:http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html

rubocop gem贡献者在Ruby风格指南中提出:

当在词法类范围中将方法混叠时,首选别名 自我的解决在这个语境中也是词汇的,而且它 清楚地向用户传达您的别名的间接信息 将不会改变在运行时或任何子类,除非作出 明确。< / p >

class Westerner
def first_name
@names.first
end


alias given_name first_name
end

当对模块、类或其他类的方法进行混叠时,总是使用alias_method 运行时的单例类,因为别名的词法范围导致 这些情况下的不可预测性

module Mononymous
def self.included(other)
other.class_eval { alias_method :full_name, :given_name }
end
end


class Sting < Westerner
include Mononymous
end

__abc0 __abc1, __abc2

old_method将在一个类或模块中声明,这个类或模块现在被继承到我们的类中,其中new_method将被使用。

可以是变量,也可以是方法。

假设Class_1有old_method, Class_2和Class_3都继承了Class_1。

如果Class_2和Class_3的初始化是在Class_1中完成的,那么两者在Class_2和Class_3中可以有不同的名称及其用法。