views:

99

answers:

3
def foo
    "foo"
end

alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s

In the above example, I expected to see the same object_id output for each method call since they reference the same method. Why do I see different object_id's? When you alias a method in Ruby doesn't the alias refer to the original object, not a copy?

+2  A: 

You're calling object_id on the object returned by foo, which is a string created in the method and thus will be different every time. You'd see the same results if you just called foo twice. It returns a new string every time. If you want a constant string, return the symbol :foo instead.

Past that, even though they share the same implementation right now, they are different methods. If you override foo to return the string "bar", foo2 will still keep returning "foo".

Chuck
Yes. I am calling object_id on the object returned by foo. I intended to call object_id on the method itself but I'm not sure if that's even possible or makes any sense. I wanted to show that foo and foo2 refer to the same method by using the object_id to reveal this.
+1  A: 

Try:

FOO = "foo"
def foo
    FOO
    end

alias foo2 foo
puts "foo2: " + foo2.object_id.to_s
puts "foo: " + foo.object_id.to_s

To get the effect you are wanting. "foo" is an expression and it gets evaluated each time the function is called. To see why this is, consider that you could just as well have written:

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
MarkusQ
Not sure I understand why the FOO constant has the effect of making the foo and foo2 methods refer to the same object_id. Your example produces the effect I was expecting but I'm not sure why the string constant is required. An alias is an alias, shouldn't it reference the same object regardless?
Don't understand why you mention that "foo" is an expression and why that is important for explaining this. I must be missing something here. Still not understanding this.
What I wanted to demonstrate is that foo and foo2 refer to the same object. That's the only reason I used the object_id method. I think the reason your example works is because you are returning a constant. foo2.object_id and foo.object_id then refer to the same object - unlike my example.
+1  A: 

Starting over with a new answer in response to your various comments.

In the example code, you are calling the method, not referencing it. You want to use

method(:foo)

to actually get the method itself and not the result of calling it.

Also, object_id is not the right way to test if two methods are the same, because method(:foo) returns a new Method object each time. For an analogy that might make this clearer, if you opened the same file twice you would have two distinct file handles even though the underlying file was the same. Instead, I think you want:

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

which, as you will see if you try it, returns true.

MarkusQ
Fantastic. Thanks so much.