UnboundMethod#hash apparently broken in 1.8.1

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

Hi –

[msg that apparently never made it when posted to c.l.r.]

···

On Sat, 28 Feb 2004, Robert Klemme wrote:

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’re describing it as broken. Can you explain
further?

David


David A. Black
dblack@wobblini.net

Hi –

“Robert Klemme” bob.news@gmx.net writes:

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

···


David A. Black
dblack@wobblini.net

(As David pointed out to me [in a META-META message] this came through
blank the first time. That happens when I sign my emails to ruby-talk
for some reason. Anyhow, here it is again…)

[msg that apparently never made it when posted to c.l.r.]

I saw this message come through the mailing list… I’ve heard you
mention (on IRC?) that the gateway isn’t working, yet I don’t think
I’ve had any trouble. Could it be you have an overzealous spam-filter
or something?

If this is a problem I’d like to get it fixed. I’m just trying to
verify the problem before we pester anyone about it. Can you give
examples of messages that have showed up on c.l.r (and are now in
Google Groups) that haven’t shown up on ruby-talk (and thus aren’t in
the archive)?

Thanks,

Nathaniel
Terralien, Inc.

<:((><

···

On Feb 28, 2004, at 13:22, David A. Black wrote:

Hi,

···

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” on 04/02/29, “David A. Black” dblack@wobblini.net writes:

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’re describing it as broken. Can you explain
further?

If Robert is claiming two hash values are different where two values
are equal (by “==”), it’s not a bug, because Hash uses “hash” to get
hash values, and uses “eql?” to compare, not “==”.

						matz.

“Tim Sutherland” timsuth@ihug.co.nz schrieb im Newsbeitrag
news:slrnc43f2p.j1r.timsuth@europa.zone…

Hi –

“Robert Klemme” bob.news@gmx.net writes:

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

In article m3ad33mpjr.fsf@wobblini.net, David Alan Black wrote:

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

···

On Mar 1, 2004, at 5:14 AM, Tim Sutherland wrote:

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.

Hi –

(As David pointed out to me [in a META-META message] this came through
blank the first time. That happens when I sign my emails to ruby-talk
for some reason. Anyhow, here it is again…)

[msg that apparently never made it when posted to c.l.r.]

I saw this message come through the mailing list… I’ve heard you
mention (on IRC?) that the gateway isn’t working, yet I don’t think
I’ve had any trouble. Could it be you have an overzealous spam-filter
or something?

The little note above is because I tried to post directly to clr and
it didn’t show up – but I think that was my Usenet provider’s fault.
The main problem is actually that messages I send to ruby-talk don’t
get posted to clr.

If this is a problem I’d like to get it fixed. I’m just trying to
verify the problem before we pester anyone about it. Can you give
examples of messages that have showed up on c.l.r (and are now in
Google Groups) that haven’t shown up on ruby-talk (and thus aren’t in
the archive)?

Again, it’s the opposite (as far as I can tell). I think ruby-talk
sees everything from clr. But the most recent ruby-talk post from me
in Google Groups is from Feb. 15. I’ve sent about 20 messages since
then, none of which appear to have made it to clr.

I too would like to get it fixed. I did actually pester someone about
it, but I’ll withhold his name as I’m not 100% sure he’s the right
person :slight_smile:

David

···

On Sun, 29 Feb 2004, Nathaniel Talbott wrote:

On Feb 28, 2004, at 13:22, David A. Black wrote:


David A. Black
dblack@wobblini.net

“Yukihiro Matsumoto” matz@ruby-lang.org schrieb im Newsbeitrag
news:1078045709.093139.10759.nullmailer@picachu.netlab.jp…

Hi,

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’re describing it as broken. Can you explain
further?

If Robert is claiming two hash values are different where two values
are equal (by “==”), it’s not a bug, because Hash uses “hash” to get
hash values, and uses “eql?” to compare, not “==”.

Ok, the behavior is consistent then. In that case I’d say #hash and
#eql? should be changed. Or is there a reason why we shouldn’t use
UnboundMethod as a hash key? To me the example with the additional meta
data for methods made perfectly sense.

Regards

robert
···

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” > on 04/02/29, “David A. Black” dblack@wobblini.net writes:

Hi,

···

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” on 04/03/02, Mark Hubbart discord@mac.com writes:

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. :wink:
I’m curious why you expect so.

						matz.

“Yukihiro Matsumoto” matz@ruby-lang.org schrieb im Newsbeitrag
news:1078185421.621148.19179.nullmailer@picachu.netlab.jp…

Hi,

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. :wink:
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
···

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” > on 04/03/02, Mark Hubbart discord@mac.com writes:

“Yukihiro Matsumoto” matz@ruby-lang.org wrote in message >

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. :wink:
I’m curious why you expect so.

matz.

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

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]

···

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” > on 04/03/02, Mark Hubbart discord@mac.com writes:

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 :slight_smile:

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

–Mark

···

On Mar 1, 2004, at 3:57 PM, Yukihiro Matsumoto wrote:

Hi,

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” > on 04/03/02, Mark Hubbart discord@mac.com writes:

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. :wink:
I’m curious why you expect so.

Hi,

···

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” on 04/03/01, “Robert Klemme” bob.news@gmx.net writes:

Ok, the behavior is consistent then. In that case I’d say #hash and
#eql? should be changed. Or is there a reason why we shouldn’t use
UnboundMethod as a hash key? To me the example with the additional meta
data for methods made perfectly sense.

I understand what you meant. I will consider the idea.

						matz.

Hi,

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

In message “Re: UnboundMethod#hash apparently broken in 1.8.1” on 04/03/03, “Its Me” itsme213@hotmail.com writes:

“Yukihiro Matsumoto” matz@ruby-lang.org wrote in message

Why not? The UnboundMethod object is a wrapper of the internal “real”
UnboundMethod.

A wrapper does explain it; but see below why I think it would be useful
otherwise.

I thought UnboundMethod is not THAT important to pay
the price to satisfy your expectation.

I don’t know enough to understand the implementation trade-offs. But uniform
access to the meta-level could be very good. I want to build a facility to
attach meta-data easily to (meta)objects. Along the lines of the new
@meta-data in Java 1.5, or the attributes in C#, but exploiting Ruby’s
flexibility.

I want to use this facility to capture structures that describe properties
of modules, classes, attributes, methods, formal parameters, exceptions,
relationships (even if implemented as attributes), …etc. These structures
may be interpreted, used to generate code and other artifacts, used
transiently or kept around for a while, used to hook in compiler extensions,
etc.

Simple examples of properties:

  • R vs. R/W attribute
  • Computed vs. Stored + auto-updated attribute
  • Types of parameters and attributes
  • Documentation (!)
  • Various propagation properties of relationships

I know there are several reasons why the following won’t work today in Ruby,
but here is one sketch:

···

class Class; def META … end; end
class UnboundMethod; def META … end; end
class Attribute; def META … end; end
class Param; def META … end; end

of course, could be more varied than single META method


class A

META meta_data_on_class_A  # assume self =A

attribute a1 META meta_data_on_attribute_a1
# build Attribute object, attach meta_data
# generate r/w methods
# assume (attribute a1) returns Attribute object

def foo (p1 META meta_1, p2 META meta_2, ...)
    # assume Param objects accessible in parameter list
    # perhaps ","  operator builds up param list
end  META meta_of_foo
# assume def...end returns UnboundMethod

end

But then I’m a relative ruby nuby …