web-dev-qa-db-ja.com

aliasまたはalias_methodのどちらを使うべきですか?

aliasalias_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

ブログの投稿リンクはこちら

345
ma11hew28

必要に応じてalias_methodを再定義できます。 (これはModuleクラスで定義されています。)

aliasの振る舞いはそのスコープによって変わり、時にはまったく予測できないことがあります。

評決:alias_methodを使う - それはあなたにより多くの柔軟性を与えます。

使用法:

def foo
  "foo"
end

alias_method :baz, :foo
375
Jacob Relkin

構文とは別に、主な違いはスコープにあります。

# 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'

Aliasの使用法では、メソッド "name"はDeveloperで定義されているメソッド "full_name"を選択できません。

これはaliasがキーワードであり、語彙的にスコープされているためです。これは、ソースコードが読み込まれた時点でselfをselfの値として扱うことを意味します。対照的にalias_methodselfを実行時に決定された値として扱います。

ソース: http://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html

55
Darme

私は、メソッド名のエイリアスを登録するためだけに '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
34
agenty

alias_methodの代わりにaliasを支持している点は、その意味がrdocによって認識され、生成されたドキュメントでは適切な相互参照が行われるのに対し、rdocはalias_methodを完全に無視することです。

33
Bruno Rohée

質問をしてから1年後に、この問題に関する新しい記事があります。

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

「たくさんの男性、とてもたくさんの心を持っている」ようです。前者の記事から、著者はalias_methodを使用することを推奨していますが、後者はaliasを使用することを提案しています。

ただし、上記のブログ記事と回答の両方に、これらの方法の一般的な概要があります。

  • エイリアスを定義されている範囲に限定したい場合はaliasを使用してください。
  • 継承クラスからアクセスできるようにするには、alias_methodを使用します。
22
Kamil Lelonek

これは現在 Ruby Style Guide で扱われています。

このコンテキストでのselfの解決方法として、字句クラススコープ内のメソッドのエイリアスにはエイリアスを使用することも語彙的であり、明示的に指定しない限り、実行時またはサブクラスによってエイリアスの間接参照は変更されない.

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
9
Doktor OSwaldo

alias_methodnew_methodold_method

old_methodは、現在クラスに継承されているクラスまたはモジュールで宣言されます。ここで、new_methodが使用されます。

これらは可変でもメソッドでも構いません。

Class_1にold_methodがあり、Class_2とClass_3の両方がClass_1を継承しているとします。

Class_2とClass_3の初期化がClass_1で行われると、Class_2とClass_3でその名前とその使用法が異なる可能性があります。

0
Ajay