Singleton method on object via define_method?

OK, I have this variable called box.

I want to define a singleton method xy on it. No problem.

However, I need a closure. So I need to use define_method
rather than def.

This is how I did it:

   class << box; self; end.class_eval { define_method(:xy) {[x,y]} }

Surely there is an easier way??

Hal

I don't think so :slight_smile: I asked this a long time ago; Guy Decoux provided the
same answer at RubyTalk:68053 and I wrote it up at

Regards,

Brian.

···

On Sat, Sep 11, 2004 at 06:48:07PM +0900, Hal Fulton wrote:

OK, I have this variable called box.

I want to define a singleton method xy on it. No problem.

However, I need a closure. So I need to use define_method
rather than def.

This is how I did it:

  class << box; self; end.class_eval { define_method(:xy) {[x,y]} }

Surely there is an easier way??

Off the top of my head I use a common lib:

module Kernal

  def metaclass
    (class << self; self; end)
  end

  def metaclass_eval(&block)
    (class << self; self; end).class_eval(&block)
  end

  def define_singleton(meth, &block)
    metaclass_eval { define_method(meth, &block) }
  end

end

T.

···

On Saturday 11 September 2004 05:48 am, Hal Fulton wrote:

OK, I have this variable called box.

I want to define a singleton method xy on it. No problem.

However, I need a closure. So I need to use define_method
rather than def.

This is how I did it:

   class << box; self; end.class_eval { define_method(:xy) {[x,y]} }

Surely there is an easier way??

--
( o _
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

Hi --

···

On Sat, 11 Sep 2004, Hal Fulton wrote:

OK, I have this variable called box.

I want to define a singleton method xy on it. No problem.

However, I need a closure. So I need to use define_method
rather than def.

This is how I did it:

   class << box; self; end.class_eval { define_method(:xy) {[x,y]} }

Surely there is an easier way??

If my Kernel#singleton_class RCR gets accepted (or if you write an ad
hoc version of it), you'll at least be able to shorten it to:

  box.singleton_class.class_eval { ... }

David

--
David A. Black
dblack@wobblini.net

"trans. (T. Onoma)" <transami@runbox.com> schrieb im Newsbeitrag news:200409110701.54011.transami@runbox.com...

···

On Saturday 11 September 2004 05:48 am, Hal Fulton wrote:

OK, I have this variable called box.

I want to define a singleton method xy on it. No problem.

However, I need a closure. So I need to use define_method
rather than def.

This is how I did it:

   class << box; self; end.class_eval { define_method(:xy) {[x,y]} }

Surely there is an easier way??

Off the top of my head I use a common lib:

module Kernal

def metaclass
   (class << self; self; end)
end

def metaclass_eval(&block)
   (class << self; self; end).class_eval(&block)
end

def define_singleton(meth, &block)
   metaclass_eval { define_method(meth, &block) }
end

end

Good! I'd just put it into class Object instead of module Kernel. That's a more appropriate place IMHO. Also "metaclass" seems the wrong term in this case, although I can see why you didn't want to use "singleton_class"...

Regards

    robert

Agreed. Better name?

···

On Sunday 12 September 2004 07:10 am, Robert Klemme wrote:

"trans. (T. Onoma)" <transami@runbox.com> schrieb im Newsbeitrag
> module Kernal
>
> def metaclass
> (class << self; self; end)
> end
>
> def metaclass_eval(&block)
> (class << self; self; end).class_eval(&block)
> end
>
> def define_singleton(meth, &block)
> metaclass_eval { define_method(meth, &block) }
> end
>
> end

Good! I'd just put it into class Object instead of module Kernel. That's
a more appropriate place IMHO. Also "metaclass" seems the wrong term in
this case, although I can see why you didn't want to use
"singleton_class"...

--
( o _
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

selfclass?

martin

···

"trans. (T. Onoma)" <transami@runbox.com> wrote:
>

> Good! I'd just put it into class Object instead of module Kernel. That's
> a more appropriate place IMHO. Also "metaclass" seems the wrong term in
> this case, although I can see why you didn't want to use
> "singleton_class"...

Agreed. Better name?

That's better. Or maybe self_class.

That could work.

···

On Sunday 12 September 2004 02:19 pm, Martin DeMello wrote:

"trans. (T. Onoma)" <transami@runbox.com> wrote:
> > Good! I'd just put it into class Object instead of module Kernel.
> > That's a more appropriate place IMHO. Also "metaclass" seems the wrong
> > term in this case, although I can see why you didn't want to use
> > "singleton_class"...
>
> Agreed. Better name?

selfclass?

--
( o _
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

Hi --

> > > Good! I'd just put it into class Object instead of module Kernel.
> > > That's a more appropriate place IMHO. Also "metaclass" seems the wrong
> > > term in this case, although I can see why you didn't want to use
> > > "singleton_class"...
> >
> > Agreed. Better name?
>
> selfclass?

That's better. Or maybe self_class.

Then you have "self.class" and "self.self_class" -- or, for that
matter, potentially "self.class" and "self_class" -- meaning different
things but looking awfully similar.

I think Matz is actually migrating from 'singleton class' to 'virtual
class'. I don't like that term very much (there's nothing really
"virtual" about it; it's a real class, once it's created, and if it's
not created, it's not even virtual), but it's probably a good idea to
keep the terminology unified.

David

···

On Mon, 13 Sep 2004, trans. (T. Onoma) wrote:

On Sunday 12 September 2004 02:19 pm, Martin DeMello wrote:
> "trans. (T. Onoma)" <transami@runbox.com> wrote:

--
David A. Black
dblack@wobblini.net

D. A. Black wrote:

I think Matz is actually migrating from 'singleton class' to 'virtual
class'. I don't like that term very much (there's nothing really
"virtual" about it; it's a real class, once it's created, and if it's
not created, it's not even virtual), but it's probably a good idea to
keep the terminology unified.

Interesting. "It's a real class, once it's created, ..." On what grounds
do you deem it to be a "real" class?

And if there were such a thing as a "virtual class", what would it be?

Cheers,
Gavin

D. A. Black wrote:
> I think Matz is actually migrating from 'singleton class' to 'virtual
> class'. I don't like that term very much (there's nothing really
> "virtual" about it; it's a real class, once it's created, and if it's
> not created, it's not even virtual), but it's probably a good idea to
> keep the terminology unified.

Interesting. "It's a real class, once it's created, ..." On what grounds
do you deem it to be a "real" class?

irb(main):001:0> c = (class << ""; self; end)
=> #<Class:#<String:0x402a8294>>
irb(main):002:0> c.class
=> Class

And if there were such a thing as a "virtual class", what would it be?

I have no idea. The term doesn't evoke anything to me.

David

···

On Mon, 13 Sep 2004, Gavin Sinclair wrote:

--
David A. Black
dblack@wobblini.net

I don't know what a "virtual class" would be in real terms, but
semantically, I'd say it's some kind of object benignly masqerading as a
class. Like a proxy object for a remote Froboz object might be said to
masquerade as a Froboz.

So just because your object above tells the world it's a "Class", I'm not
necessarily convinced. I realise that, if this _is_ a benign deception,
it's a deep one, because you'd expect the #class method to be truthful.
However, that's to be expected when we're talking about the deep internals
of Ruby.

If the singleton class of an object is not treated exactly the same as a
"normal" class in Ruby's implementation, then I think there's some
justification for the word "virtual".

Gavin

···

On Mon, 13 Sep 2004, Gavin Sinclair wrote:

D. A. Black wrote:
> I think Matz is actually migrating from 'singleton class' to
'virtual class'. I don't like that term very much (there's nothing
really "virtual" about it; it's a real class, once it's created, and
if it's not created, it's not even virtual), but it's probably a
good idea to keep the terminology unified.

Interesting. "It's a real class, once it's created, ..." On what
grounds do you deem it to be a "real" class?

irb(main):001:0> c = (class << ""; self; end)
=> #<Class:#<String:0x402a8294>>
irb(main):002:0> c.class
=> Class

And if there were such a thing as a "virtual class", what would it be?

I have no idea. The term doesn't evoke anything to me.

Gavin Sinclair wrote:

I don't know what a "virtual class" would be in real terms, but
semantically, I'd say it's some kind of object benignly masqerading as a
class. Like a proxy object for a remote Froboz object might be said to
masquerade as a Froboz.

So just because your object above tells the world it's a "Class", I'm not
necessarily convinced. I realise that, if this _is_ a benign deception,
it's a deep one, because you'd expect the #class method to be truthful. However, that's to be expected when we're talking about the deep internals
of Ruby.

If the singleton class of an object is not treated exactly the same as a
"normal" class in Ruby's implementation, then I think there's some
justification for the word "virtual".

I really think it's just a class. It has special uses, perhaps, but I don't
think it's treated specially. I can't see that it's anything other than a
real Class.

Hal

Hi --

>
>> D. A. Black wrote:
>> > I think Matz is actually migrating from 'singleton class' to
>> 'virtual class'. I don't like that term very much (there's nothing
>> really "virtual" about it; it's a real class, once it's created, and
>> if it's not created, it's not even virtual), but it's probably a
>> good idea to keep the terminology unified.
>>
>> Interesting. "It's a real class, once it's created, ..." On what
>> grounds do you deem it to be a "real" class?
>
> irb(main):001:0> c = (class << ""; self; end)
> => #<Class:#<String:0x402a8294>>
> irb(main):002:0> c.class
> => Class

>> And if there were such a thing as a "virtual class", what would it be?
>
> I have no idea. The term doesn't evoke anything to me.

I don't know what a "virtual class" would be in real terms, but
semantically, I'd say it's some kind of object benignly masqerading as a
class. Like a proxy object for a remote Froboz object might be said to
masquerade as a Froboz.

So just because your object above tells the world it's a "Class", I'm not
necessarily convinced. I realise that, if this _is_ a benign deception,
it's a deep one, because you'd expect the #class method to be truthful.
However, that's to be expected when we're talking about the deep internals
of Ruby.

If the singleton class of an object is not treated exactly the same as a
"normal" class in Ruby's implementation, then I think there's some
justification for the word "virtual".

I think this introduces an unnecessary level of complexity. You're
taking the long way around -- it's a Class object, but it's not a
class, but it acts like one, so we might as well say it is -- when in
fact it's simply a Class object. There's nothing more or less
"normal" about it than about other Class objects; the whole per-object
behavior model of Ruby is based on the idea that every object has both
a class of origin and a class of its own where the definitions
exclusive to that object reside. This isn't abnormal, nor an
aberration; it's the way the whole thing works.

David

···

On Mon, 13 Sep 2004, Gavin Sinclair wrote:

> On Mon, 13 Sep 2004, Gavin Sinclair wrote:

--
David A. Black
dblack@wobblini.net

Except that it is tied to the object and not the class hierarchy. So it is
'virtually' a class, but not quite :wink:

···

On Monday 13 September 2004 01:45 am, Hal Fulton wrote:

Gavin Sinclair wrote:
> I don't know what a "virtual class" would be in real terms, but
> semantically, I'd say it's some kind of object benignly masqerading as a
> class. Like a proxy object for a remote Froboz object might be said to
> masquerade as a Froboz.
>
> So just because your object above tells the world it's a "Class", I'm not
> necessarily convinced. I realise that, if this _is_ a benign deception,
> it's a deep one, because you'd expect the #class method to be truthful.
> However, that's to be expected when we're talking about the deep
> internals of Ruby.
>
> If the singleton class of an object is not treated exactly the same as a
> "normal" class in Ruby's implementation, then I think there's some
> justification for the word "virtual".

I really think it's just a class. It has special uses, perhaps, but I don't
think it's treated specially. I can't see that it's anything other than a
real Class.

--
( o _
// trans.
/ \ transami@runbox.com

I don't give a damn for a man that can only spell a word one way.
-Mark Twain

"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.44.0409130546200.13044-100000@wobblini...

Hi --

> So just because your object above tells the world it's a "Class", I'm

not

> necessarily convinced. I realise that, if this _is_ a benign

deception,

> it's a deep one, because you'd expect the #class method to be

truthful.

> However, that's to be expected when we're talking about the deep

internals

> of Ruby.
>
> If the singleton class of an object is not treated exactly the same as

a

> "normal" class in Ruby's implementation, then I think there's some
> justification for the word "virtual".

Originally I was going to argue that "virtual" is inappropriate because it
was deceiving. While thinking about this issue it occurred to me that
"singleton classes" aka "virtual classes" share a property with C++'s
"virtual classes": you cannot instantiate objects from them.

OTOH, you can have exactly one instance of this class, but this instance
preceedes the class (i.e. first the instance is created and then - maybe -
the class). Strictly speaking, the instance is the factory for the
class - not the other way round as it is normally.

<philosophical>I depends on everyones notion of "class" whether he or she
thinks this no longer makes it a class. Although in that case I'd be
interested to learn a more appropriate name for this
thing.</philosophical>

I think this introduces an unnecessary level of complexity. You're
taking the long way around -- it's a Class object, but it's not a
class, but it acts like one, so we might as well say it is -- when in
fact it's simply a Class object. There's nothing more or less
"normal" about it than about other Class objects;

I regard the lack of the ability to create instances a major difference.
Just as a reminder

s="foo"

=> "foo"

class << s; new ; end

TypeError: can't create instance of virtual class
        from (irb):6:in `new'
        from (irb):6

class << s; allocate ; end

TypeError: can't create instance of virtual class
        from (irb):7:in `allocate'
        from (irb):7

class << s; ancestors ; end

=> [String, Enumerable, Comparable, Object, Kernel]

the whole per-object
behavior model of Ruby is based on the idea that every object has both
a class of origin and a class of its own where the definitions
exclusive to that object reside. This isn't abnormal, nor an
aberration; it's the way the whole thing works.

Well, it's normal in Ruby. But generally speaking the naive OO expert
would expect either not to have singleton/virtual classes (SVC :-)) *or*
have Object#class return the singleton class - if that would exist. Note,
I'm not advocating to change this in any way - in fact it's good the way
it is. I just try to uncover why SVC often create confusion.

The schizophrenic thing about SVC is, that instances change their class at
most once without showing it to the outside world (i.e. #class still
returns the original class).

All this shows, what weired things men can come up with - that in practice
do work really great. :slight_smile:

Kind regards

    robert

PS: Sorry for thinking aloud...

···

On Mon, 13 Sep 2004, Gavin Sinclair wrote:

trans. (T. Onoma) wrote:

I really think it's just a class. It has special uses, perhaps, but I don't
think it's treated specially. I can't see that it's anything other than a
real Class.

Except that it is tied to the object and not the class hierarchy. So it is 'virtually' a class, but not quite :wink:

You can't create an instance of it, and you can't subclass it.
Those are the only differences I'm aware of with other classes.

The class Class can't be subclassed either. Is Class not a real class?
It is. It's just a special case.

Hal

self#protoclass ?

martin

···

Robert Klemme <bob.news@gmx.net> wrote:

OTOH, you can have exactly one instance of this class, but this instance
preceedes the class (i.e. first the instance is created and then - maybe -
the class). Strictly speaking, the instance is the factory for the
class - not the other way round as it is normally.

Hi --

Originally I was going to argue that "virtual" is inappropriate because it
was deceiving. While thinking about this issue it occurred to me that
"singleton classes" aka "virtual classes" share a property with C++'s
"virtual classes": you cannot instantiate objects from them.

Actually if C++ has virtual classes, I think that's all the more
reason for Ruby not to call them that. Any such point of contact
inevitably leads to misunderstanding and/or expectation (i.e., that
Ruby will be like the other language).

OTOH, you can have exactly one instance of this class, but this instance
preceedes the class (i.e. first the instance is created and then - maybe -
the class). Strictly speaking, the instance is the factory for the
class - not the other way round as it is normally.

<philosophical>I depends on everyones notion of "class" whether he or she
thinks this no longer makes it a class. Although in that case I'd be
interested to learn a more appropriate name for this
thing.</philosophical>

> [I wrote:]
>
> the whole per-object
> behavior model of Ruby is based on the idea that every object has both
> a class of origin and a class of its own where the definitions
> exclusive to that object reside. This isn't abnormal, nor an
> aberration; it's the way the whole thing works.

Well, it's normal in Ruby. But generally speaking the naive OO expert
would expect either not to have singleton/virtual classes (SVC :-)) *or*
have Object#class return the singleton class - if that would exist. Note,
I'm not advocating to change this in any way - in fact it's good the way
it is. I just try to uncover why SVC often create confusion.

"Naive OO expert" -- interesting :slight_smile: "Normal in Ruby" is good enough
for me, since we're talking about Ruby. Otherwise it becomes an
argument that there's an immutable/official OO model that languages
must not deviate from. (I know you don't really think this -- I'm
just extrapolating from what you're saying.)

The schizophrenic thing about SVC is, that instances change their class at
most once without showing it to the outside world (i.e. #class still
returns the original class).

I think we're looking at this backwards in this discussion. We're
looking at it as: Objects have this weird class-like thing, so what
is it? I think it's better to look at it from the other end, like
this: Objects in Ruby can have methods added to them on a per-object
basis. That's a fundamental principle of Ruby (whether it is true of
other OO languages or not). The way Matz has chosen to implement this
is by associating a second, dedicated class with each object. That's
what this class actually *is* -- it's the fulfillment of that design,
not something growing off the design that has to be explained
separately.

The details then fall into place. The fact that the class doesn't
exist until it's needn't does not have to mean that there's anything
virtual about it -- it's just a matter of efficiency, and it's
transparent. And it's a perfectly real class, because it fits the
definition of what a class can be in Ruby.

Hmmm... "dedicated_class"... hmmm... :slight_smile:

David

···

On Mon, 13 Sep 2004, Robert Klemme wrote:

--
David A. Black
dblack@wobblini.net

Hal Fulton wrote:

trans. (T. Onoma) wrote:

I really think it's just a class. It has special uses, perhaps, but I don't
think it's treated specially. I can't see that it's anything other than a
real Class.

Except that it is tied to the object and not the class hierarchy. So it is 'virtually' a class, but not quite :wink:

You can't create an instance of it, and you can't subclass it.
Those are the only differences I'm aware of with other classes.

The class Class can't be subclassed either. Is Class not a real class?
It is. It's just a special case.

Sounds sort of like a traits[1] or what Perl 6 refers to as roles[2][3]. But, then this is deeper Ruby than I'm familiar with.

Randy.

1. <http://www.cse.ogi.edu/~black/publications/TR_CSE_02-012.pdf&gt;
2. <GitHub - Raku/old-design-docs: Raku language design documents;
3. <http://search.cpan.org/~lpalmer/Class-Role-0.03/Role.pm&gt;