алиасинг метода приводит к разным объектам? - PullRequest
1 голос
/ 08 марта 2009
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, псевдоним не ссылается на оригинальный объект, а не на копию?

Ответы [ 3 ]

2 голосов
/ 09 марта 2009

Начиная с нового ответа в ответ на ваши различные комментарии.

В примере кода вы вызываете метод, а не ссылаетесь на него. Вы хотите использовать

method(:foo)

чтобы получить сам метод, а не результат его вызова.

Кроме того, object_id не является правильным способом проверки, если два метода одинаковы, потому что method(:foo) каждый раз возвращает новый объект метода. Для аналогии, которая могла бы прояснить это, если вы открываете один и тот же файл дважды, у вас будет два разных дескриптора файла, даже если базовый файл был одинаковым. Вместо этого я думаю, что вы хотите:

method(:foo) ==  method(:foo2)

который, как вы увидите, если вы попробуете это, возвращает true.

2 голосов
/ 08 марта 2009

Вы вызываете object_id для объекта, возвращаемого foo, который является строкой, созданной в методе, и поэтому каждый раз будет отличаться. Вы бы увидели те же результаты, если бы просто дважды позвонили foo. Он возвращает новую строку каждый раз. Если вы хотите постоянную строку, верните вместо нее символ :foo.

В прошлом даже при том, что они сейчас используют одну и ту же реализацию, они являются разными методами. Если вы переопределите foo для возврата строки "bar", foo2 все равно будет возвращать "foo".

1 голос
/ 08 марта 2009

Попробуйте:

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
...