aliasまたはalias_methodを使用する必要がありますか?


353

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

alias_methodの使用法

class User

  def full_name
    puts "Johnnie Walker"
  end

  alias_method :name, :full_name
end

User.new.name #=>Johnnie Walker

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


4
その投稿はあなたの質問に答えませんか?
モイヌディン2011年

4
@marcog:私はそれを一通り読みましたが、確信が持てません。メソッド内でエイリアスを定義することは、頻繁に行うべきことではありません。
Boris Stitnicky

2
@digitalextremistリンクが機能する
lukas.pukenis

4
Rubyスタイルガイドではaliasalias_method「レキシカルクラススコープでメソッドをエイリアスする場合」と「実行時にモジュール、クラス、またはシングルトンクラスのメソッドをエイリアスする場合」を推奨
bbatsov/

回答:


380

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

aliasの動作はそのスコープに応じて変化し、時にはまったく予測できない場合があります。

評決:使用alias_method-柔軟性が大幅に向上します。

使用法:

def foo
  "foo"
end

alias_method :baz, :foo

43
予測不可能とはどういう意味ですか。素朴には、柔軟性が低いオプションの方が予測しやすいと言えます。また、alias_methodを再定義することで得られるメリットの実際的な例を教えてください。
Boris Stitnicky

7
使用例:alias :new_method_name :old_method_nameORalias_method :new_method_name, :old_method_name
boulder_ruby

10
彼がここで探している言葉は、より期待される結果です。alias_methodのようにコードが読み取られるときではなく、実行時に決定されるaliasため、期待どおりに動作します。
ジョシュア・ピンター2014

4
メソッドが実行時にその場で定義されることを期待することは、ほとんどのプログラマが期待することではありません。少なくとも私にとっては豚を飛ばすようなものです。
akostadinov 2014

10
defvs. についても同じことが言えますdefine_method: " define_methodは、必要に応じて再定義できます。(Moduleクラスで定義されています。)defの動作は、そのスコープに応じて変化し、時々まったく予測できないdefine_method場合があります。柔軟性が向上しました。」
Daniel Rikowski、2017年

62

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

# 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、ソースコードが読み込まれたときの自己の値として扱うことを意味します。対照的に、は実行時に決定された値としてalias_method扱わselfれます。

出典:http : //blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html


35

alias代わりに有利な点alias_methodは、そのセマンティクスがrdocによって認識されるため、生成されたドキュメントで適切な相互参照が行われ、rdocは完全に無視することalias_methodです。


56
たぶん、RDocはalias_methodをaliasと同じように扱い始めるはずです。私たちは彼らにそれを伝える必要があります;)
SzymonJeżSep

9
RDocは、実行時に評価されるメソッドの結果をどのように理解するはずですか?

@ user1115652誰かサルにパッチを当てたかもしれないというあなたのポイントはありますalias_methodか?それは本当にありそうにないようで、誰かがそうすれば、彼らはRDocの結果に苦しむことをいとわないはずです。それが不可能であるというあなたの要点である場合、なぜあなたはそれを考え、Yardocはそれをどのように行うと思いますか?
iconoclast

35

メソッド名のエイリアスを登録するためだけに 'alias'を使用すると書かれている、(慣例のような)未記述のルールがあると思います。つまり、コードのユーザーに複数の名前を持つ1つのメソッドを提供したい場合:

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

23

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

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

それは「非常に多くの男性、非常に多くの心」のようです。前者の記事から、著者はの使用を推奨しalias_method、後者はの使用を提案していaliasます。

ただし、上記のブログ投稿と回答の両方に、これらのメソッドの共通の概要があります。

  • aliasエイリアスをそれが定義されているスコープに制限する場合に使用します
  • alias_method継承されたクラスがそれにアクセスできるようにするために使用します

16

rubocop gemの貢献者は、Rubyスタイルガイドで提案しています。

字句クラススコープでメソッドのエイリアスを設定する場合はエイリアスを優先します。これは、このコンテキストでの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

0

alias_method new_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で異なる名前を持つことができ、その使用法も異なります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.