メソッドのエイリアスは異なるオブジェクトになりますか?
-
05-07-2019 - |
質問
def foo
"foo"
end
alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s
上の例では、同じメソッドを参照しているため、各メソッド呼び出しで同じobject_id出力が表示されると予想していました。異なるobject_idが表示されるのはなぜですか? Rubyでメソッドをエイリアスすると、エイリアスはコピーではなく元のオブジェクトを参照しますか?
解決
さまざまなコメントに応じて、新しい回答からやり直します。
サンプルコードでは、メソッドを参照せずに呼び出ししています。使用したい
method(:foo)
メソッドの呼び出しの結果ではなく、実際にメソッド自体を取得します。
また、 method(:foo)
は毎回新しいMethodオブジェクトを返すため、 object_id
は2つのメソッドが同じかどうかをテストする正しい方法ではありません。これを明確にする類似点として、同じファイルを2回開いた場合、基になるファイルが同じであっても、2つの異なるファイルハンドルがあります。代わりに、私はあなたが欲しいと思う:
method(:foo) == method(:foo2)
これは、試してみるとわかるように、 true
を返します。
他のヒント
foo
によって返されるオブジェクトで object_id
を呼び出しています。これはメソッドで作成された文字列であり、そのため毎回異なります。 foo
を2回呼び出しただけで、同じ結果が表示されます。毎回新しい文字列を返します。定数文字列が必要な場合は、代わりにシンボル:foo
を返します。
過去、同じ実装を共有していても、異なる方法である 。 foo
をオーバーライドして文字列" bar"を返す場合、 foo2
は引き続き" foo"を返します。
試してください:
FOO = "foo"
def foo
FOO
end
alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s
目的の効果を得るには。 " foo"は式であり、関数が呼び出されるたびに評価されます。これがなぜなのかを見るために、次のように書くこともできたと考えてください。
def foo
"It is now #{Time.now}"
end
alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s