UnboundMethod#hash apparently broken in 1.8.1

R

Robert Klemme

Hi all,

one can't use UnboundMethod as a hash key:

irb(main):001:0> class Foo; def bar;end; end
=> nil
irb(main):002:0> Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):003:0> a = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):004:0> b = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):005:0> a == b
=> true
irb(main):006:0> b == a
=> true
irb(main):007:0> a.hash == b.hash
=> false
irb(main):008:0> a.id
=> 135052720
irb(main):009:0> a.hash
=> 135052720
irb(main):010:0> b.id
=> 135044800
irb(main):011:0> b.hash
=> 135044800

UnboundMethod#hash is broken in
$ ruby --version
ruby 1.8.1 (2003-12-25) [i386-cygwin]

Is that fixed in a later version?

Kind regards

robert
 
D

David Alan Black

Hi --

Robert Klemme said:
Hi all,

one can't use UnboundMethod as a hash key:

irb(main):001:0> class Foo; def bar;end; end
=> nil
irb(main):002:0> Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):003:0> a = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):004:0> b = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):005:0> a == b
=> true
irb(main):006:0> b == a
=> true
irb(main):007:0> a.hash == b.hash
=> false
irb(main):008:0> a.id
=> 135052720
irb(main):009:0> a.hash
=> 135052720
irb(main):010:0> b.id
=> 135044800
irb(main):011:0> b.hash
=> 135044800

UnboundMethod#hash is broken in
$ ruby --version
ruby 1.8.1 (2003-12-25) [i386-cygwin]

Is that fixed in a later version?

I'm not sure why you describe it as broken. Can you explain
a little further?


David
 
T

Tim Sutherland

Hi --

Robert Klemme said:
Hi all,

one can't use UnboundMethod as a hash key:

irb(main):001:0> class Foo; def bar;end; end
=> nil
irb(main):002:0> Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):003:0> a = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):004:0> b = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):005:0> a == b
=> true
irb(main):006:0> b == a
=> true
irb(main):007:0> a.hash == b.hash
=> false
irb(main):008:0> a.id
=> 135052720
irb(main):009:0> a.hash
=> 135052720
irb(main):010:0> b.id
=> 135044800
irb(main):011:0> b.hash
=> 135044800

UnboundMethod#hash is broken in
$ ruby --version
ruby 1.8.1 (2003-12-25) [i386-cygwin]

Is that fixed in a later version?

I'm not sure why you describe it as broken. Can you explain
a little further?

I think he means because "a == b" but "!a.eql?(b)" and "a.hash != b.hash".
It's not a bug, just a lack of a feature.

I posted a similar message today about Sets.
 
R

Robert Klemme

Tim Sutherland said:
Hi --

Robert Klemme said:
Hi all,

one can't use UnboundMethod as a hash key:

irb(main):001:0> class Foo; def bar;end; end
=> nil
irb(main):002:0> Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):003:0> a = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):004:0> b = Foo.instance_method( :bar )
=> #<UnboundMethod: Foo#bar>
irb(main):005:0> a == b
=> true
irb(main):006:0> b == a
=> true
irb(main):007:0> a.hash == b.hash
=> false
irb(main):008:0> a.id
=> 135052720
irb(main):009:0> a.hash
=> 135052720
irb(main):010:0> b.id
=> 135044800
irb(main):011:0> b.hash
=> 135044800

UnboundMethod#hash is broken in
$ ruby --version
ruby 1.8.1 (2003-12-25) [i386-cygwin]

Is that fixed in a later version?

I'm not sure why you describe it as broken. Can you explain
a little further?

I think he means because "a == b" but "!a.eql?(b)" and "a.hash != b.hash".
Exactly.

It's not a bug, just a lack of a feature.

I regard it rather as a bug than a lack of a feature - but I'd agree that
it's debatable. My point is that you can't use UnboundMethod as hash key
because of this although it would make pretty much sense. (See the other
thread about attaching meta data to methods and classes)

Regards

robert
 
M

Mark Hubbart

I think he means because "a == b" but "!a.eql?(b)" and "a.hash !=
b.hash".
It's not a bug, just a lack of a feature.

irb(main):006:0> class Foo;def bar;end;end
=> nil
irb(main):007:0> Foo.instance_method:)bar).hash
=> 187786
irb(main):008:0> Foo.instance_method:)bar).hash
=> 170366
irb(main):009:0> Foo.instance_method:)bar).hash
=> 155876
irb(main):010:0> Foo.instance_method:)bar).hash
=> 139386

To me, at least, this behavior is unexpected. I would expect it to
return the same object each time; or at least objects with the same
hash value.

--Mark
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: UnboundMethod#hash apparently broken in 1.8.1"

|To me, at least, this behavior is unexpected. I would expect it to
|return the same object each time; or at least objects with the same
|hash value.

I think you're expecting too much. ;-)
I'm curious why you expect so.

matz.
 
R

Robert Klemme

Yukihiro Matsumoto said:
Hi,

In message "Re: UnboundMethod#hash apparently broken in 1.8.1"

|To me, at least, this behavior is unexpected. I would expect it to
|return the same object each time; or at least objects with the same
|hash value.

I think you're expecting too much. ;-)
I'm curious why you expect so.

At least both UnboundMethod instances refer the same instance method, i.e.
the same thing if you like. So if put into a Set or Hash (as key) I'd
expect them to be treated as equivalent. Is there a reason why they
shouldn't? Can they be in a state where they no longer refer the same
method? AFAIK UnboundMethod#bind returns a new instance:

irb(main):001:0> class Foo;def bar;end;end
=> nil
irb(main):002:0> m=Foo.instance_method :bar
=> #<UnboundMethod: Foo#bar>
irb(main):003:0> f=Foo.new
=> #<Foo:0x1018b4a0>
irb(main):004:0> x = m.bind f
=> #<Method: Foo#bar>
irb(main):005:0> m
=> #<UnboundMethod: Foo#bar>
irb(main):006:0> m.id
=> 135031972
irb(main):007:0> x.id
=> 135021280
irb(main):008:0>

Kind regards

robert
 
M

Mark Hubbart

Hi,

In message "Re: UnboundMethod#hash apparently broken in 1.8.1"

|To me, at least, this behavior is unexpected. I would expect it to
|return the same object each time; or at least objects with the same
|hash value.

I think you're expecting too much. ;-)
I'm curious why you expect so.

I would expect it to work that way because both UnboundMethods are
pointing at the same exact method. Perhaps I am expecting too much,
since I don't know how it works internally. But, from the outside, I
expected it to essentially make another reference to that method's
object and pass it back.

I'm guessing (from your reaction) that what actually happens behind the
scenes when you retrieve an UnboundMethod that way is entirely
different from what I had assumed? If, in retrieving the UnboundMethod
object, it creates a new wrapper object, and passes that back, it would
make perfect sense that the hashes and ids wouldn't match. Even so, I
wish they would match :)

Of course, I'm only inferring, so I could easily be way way out in left
field here.

--Mark
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: UnboundMethod#hash apparently broken in 1.8.1"

|Imho, they should be the same object. Why should
| Foo.instance_method :)bar).id
| Foo.instance_method:)bar).id
|return two different ids?

Why not? The UnboundMethod object is a wrapper of the internal "real"
UnboundMethod. I thought UnboundMethod is not THAT important to pay
the price to satisfy your expectation.

|What if I want to extend class UnboundMethod so that I can add custom
|meta-data to UnboundMethod objects?
|
| Foo.instance_method:)bar).arg_list = [:arg1, :arg2, :arg3]

They don't have same id (for these are different Ruby object), but
they are referring the same unbound method.

matz.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top