Singleton method on object via define_method?

H

Hal Fulton

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
 
B

Brian Candler

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

I don't think so :) I asked this a long time ago; Guy Decoux provided the
same answer at RubyTalk:68053 and I wrote it up at
http://www.rubygarden.org/ruby/ruby?SingletonTutorial

Regards,

Brian.
 
T

trans. (T. Onoma)

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.

--
( o _
// trans.
/ \ (e-mail address removed)

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

Robert Klemme

trans. (T. Onoma) said:
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
 
T

trans. (T. Onoma)

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?

--
( o _
// trans.
/ \ (e-mail address removed)

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

trans. (T. Onoma)

selfclass?

That's better. Or maybe self_class.

That could work.

--
( o _
// trans.
/ \ (e-mail address removed)

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

David A. Black

Hi --

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
 
G

Gavin Sinclair

D. A. Black said:
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

David A. Black

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
 
G

Gavin Sinclair

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

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

Gavin
 
H

Hal Fulton

Gavin said:
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
 
T

trans. (T. Onoma)

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 ;)

--
( o _
// trans.
/ \ (e-mail address removed)

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

Hal Fulton

trans. (T. Onoma) said:
Except that it is tied to the object and not the class hierarchy. So it is
'virtually' a class, but not quite ;)

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
 
R

Randy W. Sims

Hal said:
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>
2. <http://dev.perl.org/perl6/apocalypse/A12.html>
3. <http://search.cpan.org/~lpalmer/Class-Role-0.03/Role.pm>
 
G

gabriele renzi

Randy W. Sims ha scritto:
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.

I think traits mostly are what we call modules
 
D

David A. Black

Hi --

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
 
R

Robert Klemme

David A. Black said:

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. said:
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
TypeError: can't create instance of virtual class
from (irb):6:in `new'
from (irb):6TypeError: can't create instance of virtual class
from (irb):7:in `allocate'
from (irb):7=> [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. :)

Kind regards

robert


PS: Sorry for thinking aloud...
 
M

Martin DeMello

Robert Klemme said:
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.

self#protoclass ?

martin
 
D

David A. Black

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. said:
[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 :) "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... :)


David
 

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

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top