我应该使用别名还是alias_method?

ma1*_*w28 349 ruby alias

我在aliasvs. 上发现了一篇博文alias_method.如该博客文章中给出的示例所示,我只想在同一个类中将方法别名为另一个.我应该使用哪个?我总是看到alias用过,但有人告诉我alias_method更好.

别名的用法

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias name full_name
end

User.new.name #=>Johnnie Walker
Run Code Online (Sandbox Code Playgroud)

alias_method的用法

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker
Run Code Online (Sandbox Code Playgroud)

博客帖子链接在这里

Jac*_*kin 376

alias_method如果需要可以重新定义.(它在Module课堂上定义.)

alias行为的变化取决于其范围,有时可能非常难以预测.

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

用法:

def foo
  "foo"
end

alias_method :baz, :foo
Run Code Online (Sandbox Code Playgroud)

  • 你的意思是不可预测的.天真地,人们会说,灵活性较低的选项将更具可预测性.另外,您能提供任何从重新定义alias_method中受益的实际示例吗? (43认同)
  • 他正在寻找的这个词是**预期的**结果.`alias_method`是在运行时确定的,而不是在读取代码时,比如'alias`,所以它表现得更像我们期望**它. (10认同)
  • 人们可以为`def`与`define_method`争论相同:"`define_method`可以在需要时重新定义.(它在`Module`类中定义.)`def`的行为根据其范围而变化有时候变得难以预测.结论:使用`define_method` - 它给你更大的灵活性." (8认同)
  • 示例用例:`别名:new_method_name:old_method_name`或`alias_method:new_method_name,:old_method_name` (7认同)
  • 期望在运行时动态定义方法并不是大多数程序员所期望的.至少就像飞猪一样. (4认同)

Dar*_*rme 58

除语法外,主要区别在于范围界定:

# 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'
Run Code Online (Sandbox Code Playgroud)

在上面的情况下,方法"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'
Run Code Online (Sandbox Code Playgroud)

使用别名时,方法"name"无法选择Developer中定义的方法"full_name".

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

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

  • 由于这个答案给出了有关范围影响的实际示例,因此我比接受的答案更喜欢它。 (2认同)

Bru*_*hée 35

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

  • 也许RDoc应该开始像别名一样对alias_method进行处理.我们应该告诉他们;) (56认同)
  • 完全同意.如果我没记错的话,Yard处理得很好...... (9认同)
  • RDoc如何理解在运行时评估的方法的后果? (9认同)
  • @user1115652 你的意思是有人_可能有_猴子补丁的“alias_method”吗?这似乎_真的_不太可能,如果有人这样做,那么他们应该愿意在 RDoc 中承担后果。如果你的观点是这是不可能的,那么你为什么这么认为以及你认为 Yardoc 是如何做到的? (2认同)

小智 35

我认为有一个不成文的规则(类似于约定),只是为了注册方法名别名而使用"别名",意味着如果你想给你的代码用户一个带有多个名字的方法:

class Engine
  def start
    #code goes here
  end
  alias run start
end
Run Code Online (Sandbox Code Playgroud)

如果您需要扩展代码,请使用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
Run Code Online (Sandbox Code Playgroud)


Kam*_*nek 22

询问问题一年后,有关该主题的新文章:

http://erniemiller.org/2014/10/23/in-defense-of-alias/

似乎"这么多男人,这么多头脑." 从前一篇文章作者鼓励使用alias_method,而后者建议使用alias.

但是,在上面的博文和答案中都有这些方法的共同概述:

  • alias当您想要将别名限制到定义它的范围时使用
  • 用于alias_method允许继承的类访问它


Dok*_*ldo 12

现在在Ruby样式指南中处理:

在词法类作用域中使用别名方法时,首选别名,因为此上下文中self的解析也是词法,并且它清楚地向用户传达,除非明确指出,否则别名的间接不会在运行时或任何子类中更改.

class Westerner
  def first_name
   @names.first
  end

 alias given_name first_name
end
Run Code Online (Sandbox Code Playgroud)

在运行时对模块,类或单例类的别名方法进行别名时始终使用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
Run Code Online (Sandbox Code Playgroud)