Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Can't bind a singleton method to a subclass?

Reply
Thread Tools

Can't bind a singleton method to a subclass?

 
 
David Walker
Guest
Posts: n/a
 
      11-08-2006
The behavior of this snippet doesn't make sense to me:

class A
def A.class_method
puts "Class method worked in #{self}"
end
end

class B < A; end

aklass = (class << A; self; end)
bklass = (class << B; self; end)

p RUBY_VERSION

A.class_method
B.class_method

p A.method(:class_method)
p B.method(:class_method)
p aklass.instance_method(:class_method)
p bklass.instance_method(:class_method)
p A.method(:class_method).unbind
p B.method(:class_method).unbind
p A.method(:class_method).unbind.bind(A)
p B.method(:class_method).unbind.bind(B)

The output (for me) is:

"1.8.4"
Class method worked in A
Class method worked in B
#<Method: A.class_method>
#<Method: B(A).class_method>
#<UnboundMethod: #<Class:A>#class_method>
#<UnboundMethod: #<Class:A>#class_method>
#<UnboundMethod: #<Class:A>#class_method>
#<UnboundMethod: #<Class:A>#class_method>
#<Method: A.class_method>
/workplace2/test.rb:24:in `bind': singleton method called for a
different object (TypeError)
from /workplace2/test.rb:24

In my mind, the last call should succeed, instead of raising an error.
Is it just plain impossible to re-bind the method to yield a #<Method:
B(A).class_method>?

--
=D ave

 
Reply With Quote
 
 
 
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-08-2006
Hi --

On Wed, 8 Nov 2006, David Walker wrote:

> The behavior of this snippet doesn't make sense to me:
>
> class A
> def A.class_method
> puts "Class method worked in #{self}"
> end
> end
>
> class B < A; end
>
> aklass = (class << A; self; end)
> bklass = (class << B; self; end)
>
> p RUBY_VERSION
>
> A.class_method
> B.class_method
>
> p A.method(:class_method)
> p B.method(:class_method)
> p aklass.instance_method(:class_method)
> p bklass.instance_method(:class_method)
> p A.method(:class_method).unbind
> p B.method(:class_method).unbind
> p A.method(:class_method).unbind.bind(A)
> p B.method(:class_method).unbind.bind(B)
>
> The output (for me) is:
>
> "1.8.4"
> Class method worked in A
> Class method worked in B
> #<Method: A.class_method>
> #<Method: B(A).class_method>
> #<UnboundMethod: #<Class:A>#class_method>
> #<UnboundMethod: #<Class:A>#class_method>
> #<UnboundMethod: #<Class:A>#class_method>
> #<UnboundMethod: #<Class:A>#class_method>
> #<Method: A.class_method>
> /workplace2/test.rb:24:in `bind': singleton method called for a
> different object (TypeError)
> from /workplace2/test.rb:24
>
> In my mind, the last call should succeed, instead of raising an error.
> Is it just plain impossible to re-bind the method to yield a #<Method:
> B(A).class_method>?


The fact that B can call A.class_method is due to the special-casing
of singleton classes of Class objects; it's the one case where a given
object can execute singleton methods of another object. But those
singleton methods still belong, unambiguously, to the first object, A.
The reason B can call them is that A's singleton class serves as the
superclass of B's singleton class -- so class_method lies on the
method look-up path of B. But class_method is still defined only in
A's singleton class.


David

--
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

 
Reply With Quote
 
 
 
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      11-08-2006
On Wed, 8 Nov 2006 wrote:

> The fact that B can call A.class_method is due to the special-casing of
> singleton classes of Class objects; it's the one case where a given object
> can execute singleton methods of another object. But those singleton
> methods still belong, unambiguously, to the first object, A. The reason B
> can call them is that A's singleton class serves as the superclass of B's
> singleton class -- so class_method lies on the method look-up path of B.
> But class_method is still defined only in A's singleton class.


still, quiet odd that one can do this

>> p B.method(:class_method).unbind


meaning, it's strange that you can 'unbind' from a class something which
cannot be bound to it and yet must have been for the initial call to 'unbind'
to succeed - a contradiction.

interesting.

-a
--
my religion is very simple. my religion is kindness. -- the dalai lama

 
Reply With Quote
 
David Walker
Guest
Posts: n/a
 
      11-08-2006
On 11/7/06, <> wrote:
> The fact that B can call A.class_method is due to the special-casing
> of singleton classes of Class objects; it's the one case where a given
> object can execute singleton methods of another object. But those
> singleton methods still belong, unambiguously, to the first object, A.
> The reason B can call them is that A's singleton class serves as the
> superclass of B's singleton class -- so class_method lies on the
> method look-up path of B. But class_method is still defined only in
> A's singleton class.


Thanks for the info. That's mostly what I thought - I guess I should
have said, "This seems silly to me," not, "This doesn't make sense to
me."

How, though, is this a special case? For instance methods, you can
bind an instance method to any object who's class is <= the class the
method is defined on. Why should it be different for singletons? I.e.
I have an instance method (instance from the perspective of the
singleton class A), I should be able to bind it to an object who's
class is a subclass of the class the instance is defined on. If A's
singleton class is a superclass of B's singleton class (which it ought
to be) then this relation holds. I think.

In any case, "B.method(:class_method)" gave me a #<Method:
B(A).class_method>. My original question still stands: is there no way
to recover this binding once it's been unbound?

--
=D ave

 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-08-2006
Hi --

On Wed, 8 Nov 2006, David Walker wrote:

> On 11/7/06, <> wrote:
>> The fact that B can call A.class_method is due to the special-casing
>> of singleton classes of Class objects; it's the one case where a given
>> object can execute singleton methods of another object. But those
>> singleton methods still belong, unambiguously, to the first object, A.
>> The reason B can call them is that A's singleton class serves as the
>> superclass of B's singleton class -- so class_method lies on the
>> method look-up path of B. But class_method is still defined only in
>> A's singleton class.

>
> Thanks for the info. That's mostly what I thought - I guess I should
> have said, "This seems silly to me," not, "This doesn't make sense to
> me."
>
> How, though, is this a special case?


What I mean is: the fact that you can call B.class_method, even though
class_method is a singleton method of an object other than B, is a
special dispensation for class objects.

> For instance methods, you can
> bind an instance method to any object who's class is <= the class the
> method is defined on. Why should it be different for singletons? I.e.
> I have an instance method (instance from the perspective of the
> singleton class A), I should be able to bind it to an object who's
> class is a subclass of the class the instance is defined on. If A's
> singleton class is a superclass of B's singleton class (which it ought
> to be) then this relation holds. I think.


I guess it's just a matter of how the logic cascades. Forbidding a
rebinding of a singleton method on a different object takes precedence
over the special situation where class singleton methods are sort of
not really singleton (i.e., can be called by subclasses).

> In any case, "B.method(:class_method)" gave me a #<Method:
> B(A).class_method>. My original question still stands: is there no way
> to recover this binding once it's been unbound?


Maybe, but not that I can think of.


David

--
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-08-2006
Hi --

On Wed, 8 Nov 2006, wrote:

> On Wed, 8 Nov 2006 wrote:
>
>> The fact that B can call A.class_method is due to the special-casing of
>> singleton classes of Class objects; it's the one case where a given
>> object
>> can execute singleton methods of another object. But those singleton
>> methods still belong, unambiguously, to the first object, A. The reason
>> B
>> can call them is that A's singleton class serves as the superclass of B's
>> singleton class -- so class_method lies on the method look-up path of B.
>> But class_method is still defined only in A's singleton class.

>
> still, quiet odd that one can do this
>
>>> p B.method(:class_method).unbind

>
> meaning, it's strange that you can 'unbind' from a class something which
> cannot be bound to it and yet must have been for the initial call to
> 'unbind'
> to succeed - a contradiction.


I think it's not so much that you're unbinding it *from* B, as that
you're grabbing it *through* B. So, by the time you unbind it, it
doesn't "know" that you got it that way; it's just a Method object,
and it allows itself to be unbound. I'd say that's a side-effect of
the fact that A's singleton methods can be got at via B at all.

Going the other way, though, it does "know" that you're trying to bind
it to something other than the object in whose singleton class it's
defined.


David

--
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      11-08-2006
On Wed, 8 Nov 2006 wrote:

> I think it's not so much that you're unbinding it *from* B, as that you're
> grabbing it *through* B. So, by the time you unbind it, it doesn't "know"
> that you got it that way; it's just a Method object, and it allows itself to
> be unbound.


yeah. at first i thought that, but:

harp:~ > cat a.rb
class A
def self.class_method() 42 end
end
class B < A; end

p A.method(:class_method)
p B.method(:class_method)


harp:~ > ruby a.rb
#<Method: A.class_method>
#<Method: B(A).class_method>

so it seems like the method is aware that it's receiver is B. but i take your
point.

> I'd say that's a side-effect of the fact that A's singleton
> methods can be got at via B at all.


yes. put another way, and something i was be-moaning several years ago, is
this:

harp:~ > cat a.rb
class A
SINGLETON_CLASS = class << self
self
end
end
class B < A
SINGLETON_CLASS = class << self
self
end
end

p B::SINGLETON_CLASS.ancestors

harp:~ > ruby a.rb
[Class, Module, Object, Kernel]

singleton classes should respect inheritence.

regards.

-a
--
my religion is very simple. my religion is kindness. -- the dalai lama

 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-08-2006
Hi --

On Wed, 8 Nov 2006, wrote:

> On Wed, 8 Nov 2006 wrote:
>
>> I think it's not so much that you're unbinding it *from* B, as that
>> you're
>> grabbing it *through* B. So, by the time you unbind it, it doesn't
>> "know"
>> that you got it that way; it's just a Method object, and it allows itself
>> to
>> be unbound.

>
> yeah. at first i thought that, but:
>
> harp:~ > cat a.rb
> class A
> def self.class_method() 42 end
> end
> class B < A; end
>
> p A.method(:class_method)
> p B.method(:class_method)
>
>
> harp:~ > ruby a.rb
> #<Method: A.class_method>
> #<Method: B(A).class_method>
>
> so it seems like the method is aware that it's receiver is B. but i take
> your point.


Interesting. The dot is the singleton-method indicator in that
notation:

irb(main):013:0> obj = Object.new
=> #<Object:0xb7f04aa8>
irb(main):014:0> def obj.x; end
=> nil
irb(main):015:0> obj.method()
=> #<Method: #<Object:0xb7f04aa8>.x>

In your example, it's A.class_method and not
#<Class:0xabcdef>.class_method. But it still really means the
singleton class of A. I guess it's all in the service of allowing for
that special case singleton-of-Class-object thing.

>> I'd say that's a side-effect of the fact that A's singleton
>> methods can be got at via B at all.

>
> yes. put another way, and something i was be-moaning several years ago, is
> this:
>
> harp:~ > cat a.rb
> class A
> SINGLETON_CLASS = class << self
> self
> end
> end
> class B < A
> SINGLETON_CLASS = class << self
> self
> end
> end
>
> p B::SINGLETON_CLASS.ancestors
>
> harp:~ > ruby a.rb
> [Class, Module, Object, Kernel]
>
> singleton classes should respect inheritence.


I'm not sure what you mean here. Is it that ancestors doesn't show
singleton classes?


David

--
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      11-08-2006
On Wed, 8 Nov 2006 wrote:

>> yes. put another way, and something i was be-moaning several years ago, is
>> this:
>>
>> harp:~ > cat a.rb
>> class A
>> SINGLETON_CLASS = class << self
>> self
>> end
>> end
>> class B < A
>> SINGLETON_CLASS = class << self
>> self
>> end
>> end
>>
>> p B::SINGLETON_CLASS.ancestors
>>
>> harp:~ > ruby a.rb
>> [Class, Module, Object, Kernel]
>>
>> singleton classes should respect inheritence.

>
> I'm not sure what you mean here. Is it that ancestors doesn't show
> singleton classes?


i meant that B's singleton class should inherit from A's singleton class - the
fact that it does not leads to all sorts of suprising behaviour...


-a
--
my religion is very simple. my religion is kindness. -- the dalai lama

 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-08-2006
Hi --

On Wed, 8 Nov 2006, wrote:

> On Wed, 8 Nov 2006 wrote:
>
>>> yes. put another way, and something i was be-moaning several years ago,
>>> is
>>> this:
>>>
>>> harp:~ > cat a.rb
>>> class A
>>> SINGLETON_CLASS = class << self
>>> self
>>> end
>>> end
>>> class B < A
>>> SINGLETON_CLASS = class << self
>>> self
>>> end
>>> end
>>>
>>> p B::SINGLETON_CLASS.ancestors
>>>
>>> harp:~ > ruby a.rb
>>> [Class, Module, Object, Kernel]
>>>
>>> singleton classes should respect inheritence.

>>
>> I'm not sure what you mean here. Is it that ancestors doesn't show
>> singleton classes?

>
> i meant that B's singleton class should inherit from A's singleton
> class - the fact that it does not leads to all sorts of suprising
> behaviour...


I'm still not seeing where your example fits in with this (I assume
I'm just being thick and not seeing what's right in front of me) --
but I'll forge ahead and note that the question of the subclass
relation of singleton classes seems to have swung back and forth. In
1.8.2, this was true (given the usual singleton_class method):

B.singleton_class.superclass == A.singleton_class

and it's true in fairly recent 1.9, but not true in 1.8.5. I have no
idea why not. B.meth still looks in A's singleton class for "meth",
but apparently inheritance is not used as the mechanism.


David

--
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Singleton methods without the singleton class Charles Oliver Nutter Ruby 4 03-22-2010 10:46 PM
Singleton object vs. enhancing singleton class Paul McMahon Ruby 3 06-09-2008 06:05 AM
Singleton Modules rather than Singleton Classes Trans Ruby 12 09-14-2007 06:45 AM
Singleton - Whether Cloneable overrides Singleton Proton Projects - Moin Java 4 03-27-2007 02:59 AM
Singleton classes and Singleton pattern Wilhelm Ruby 1 10-11-2006 01:08 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57