質問

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top