[RCR] Object#inside_metaclass?

A

Ara.T.Howard

I disagree; I think Ara was using the term "metaclass" to mean "singleton
class". I'm taking my cue from his sample code:

# (top level code)

p inside_metaclass? # false

class << self
p inside_metaclass? # true
end

So his concept of "inside a metaclass" includes "inside a non-class object's
singleton class" (since top-level self is not a class).

it does - but inadvertently. the only requirement i have is to determine
'inside_metaclass?' as in

class C
class << self
p inside_metaclass? # true
end
end

the singleton meaning accreted itself into my impl in a moment of stupidity
;-(
He then predicates that his code only works iff "all metaclasses descend
from the metaclass of Object", but if he's using "metaclass" to mean the
same thing he meant it to mean in "inside_metaclass?", then this means
singleton class (and the statement is false).

you are right. i didn't mean it - honest! my need to is to have context
sensitive class methods

class C
method # does something
class << self
method # does another thing
end
end

and that's all.
(I'm working in the dark a little here as the examples all print 'false' for
me in 1.8.2 and slightly old 1.9. I guess Ara's using a recent 1.9 -- ?)

hmm. here's mine:

jib:~/eg/ruby > cat a.rb
class Class
def inside_metaclass?
inspect =~ %r/^#<Class:/ ? true : false
end
end

class << self
p inside_metaclass?
end
class C
p inside_metaclass?
class << self
p inside_metaclass?
class << self
p inside_metaclass?
end
end
end

jib:~/eg/ruby > ruby a.rb
true
false
true
true

but this has been pointed out to break for anonymous classes. arggh.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
A

Ara.T.Howard

Hi --


(Just out of curiosity: do you mean to depart from the usual C.a here?
And why? :)

i've got a couple of coding conventions i use including:

- collections are plural
- class methods get called with ::

they help me know things like

p configs #=> this is an array of configs

x::send('method', *args) #=> x is a class

they are just habbits.
@a = @trait_defaults['class']['a'] unless defined? @a
@a
end

def a
@a = @trait_defaults['instance']['a'] unless defined? @a
@a
end
end

so i need to know, at the point of definition if we're inside a
metaclass to generate the code slightly differently. all the above
is for explanation only and is nothing like real code.

I understand the not real code point, but still, it's showing something I
can't quite follow, namely the @trait_defaults instance variable in the
instance method definition (def a). Do you mean this to refer to the
class's instance variable?

yes - sorry. both class methods AND instance methods must look up there
respective defaults in a class instance var.

you can read the real code at

http://codeforpeople.com/lib/ruby/traits/traits-0.0.0/
I'm also not sure where inside_metaclass? would go here. Can you rewrite it
into pseudo-code looking how it would look if that method existed?

class Class
def trait(*args)
if inside_metaclass?
define_class_traits(*args)
else
define_instance_traits(*args)
end
end
def class_trait(*args)
class << self
trait(*args)
end
end
end

make sense? obviously this would be easy if traits were like 'attr' and just
eval'd some code - but the defaults thing makes it hard since the defaults
must be stored somewhere in the case of instance traits and looked up later -
therefore the method definition of the trait itself must dynamically differ.
this is unlike attr_ methods. another reason for inside_metaclass? is that
traits works like

jib:~ > cat a.rb
require 'traits'
class C
class_trait 'a' => 42
class << self
trait 'b' => 'forty-two'
end
trait 'a' => 42.0
end

p C::reader_traits
p C::class_reader_traits

jib:~ > ruby a.rb
["a"]
["a", "b"]

now, 'reader_traits' and 'class_reader_traits' are also implemented like

def reader_traits(*args)
...
end
def class_reader_traits(*args)
class << self
reader_traits(*args)
end
end

eg. the __return__ value of reader_traits is context sensitive to being in/out
of a metaclass.

reason three:

jib:~ > cat a.rb
class C
p ancestors
class << self
p ancestors
end
end

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

now imagine you want to implement 'inheritence' for traits that use class @vars
(not @@vars) for default values (for the obvious reason). you need to look up
the chain of ancestors to find you defaults. problem: your ancestors vary
according to scope. i solve this by

klass =
if inside_metaclass?
pop_up_to_instance_klass
else
self
end

klass.ancestors.each{|a| look_for_default a }

the problem all boils down to this : attr_ and friends work exactly the same
whether called at a class or metaclass level. adding features like having
default values, inheritence of stuff, etc. makes the distinction of where you
are (class or metaclass) suddenly very important.

i hope i'm making myself clear now - i never meant for this to end up like
this! ;-)

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
D

David A. Black

Hi --

it does - but inadvertently. the only requirement i have is to determine
'inside_metaclass?' as in

class C
class << self
p inside_metaclass? # true
end
end

the singleton meaning accreted itself into my impl in a moment of stupidity
;-(


you are right. i didn't mean it - honest! my need to is to have context
sensitive class methods

I believe you! :) I just extrapolated from that one example and got
us sidetracked.


David
 
C

Carlos

[[email protected], 2005-05-04 20.44 CEST]
hmm - seems like something like that could work alright... but this fails: [...]
it's not easy...

If you don't need to distinguish between singleton classes for classes and
normal objects, what's the problem with

def inside?
self.is_a?(Class) &&
self.name.empty?
self.ancestors.first != self
end

?
 
I

Ilias Lazaridis

David said:
Hi -- On Thu, 5 May 2005, Mark Hubbart wrote: [...]
All the more reason to give them a different name... At this point,
I care very little what they're called; virtual class, idioclass,
own class, whatever. Just give us a nice, non-overlapping name to
call them by. I guess singleton class will have to do until then,
though...

Actually one would not want a completely separate name, for the
reason that the almost-metaclasses really are singleton classes.
Anything generated by:

class << self; self; end

is a singleton class.

no, it is not.

anything generated by (class << self; self; end)

has not _any_ instance.

Thus it is not a singleton class (which has _one_ instance)

-

It is a hidden class, a virtual class, or simply an "x-class".

x stands for "anything" / "mystery".

x stands for "exclusive" (to _one_ object)

object.xclass.

"singleton class" => x class


http://lazaridis.com/case/lang/ruby/index.html
If 'self' is a Class object, then the
resulting singleton class is also an almost-metaclass
(parametaclass?!). But it doesn't cease to be a singleton class.

almost-metaclasses => meta-objects

or

xclass of class-obj

-

The first step to "break" out of the confusion is to release to term
"singleton-class", which has a specific meaning.

..
 
A

Ara.T.Howard

[[email protected], 2005-05-04 20.44 CEST]
hmm - seems like something like that could work alright... but this fails: [...]
it's not easy...

If you don't need to distinguish between singleton classes for classes and
normal objects, what's the problem with

def inside?
self.is_a?(Class) &&
self.name.empty?
self.ancestors.first != self
end

ha! first i noticed you made a typo (the first two lines are a no-op without
another '&&') - and then i ran it anyhow. funny thing is it seems the last
line is all that's needed (if defined in Class)!

jib:~/eg/ruby > cat a.rb
class Class
def inside_metaclass?
self.ancestors.first != self
end
end

class << self
p inside_metaclass? # true
end

class C
p inside_metaclass? # false
class << self
p inside_metaclass? # true
class << self
p inside_metaclass? # true
end
end
end

p Class::new.inside_metaclass? # false
class << Class::new
p inside_metaclass? # true
end

p self.class.inside_metaclass? # false

class << self
p inside_metaclass? # true
end

jib:~/eg/ruby > ruby a.rb
true
false
true
true
false
true
false
true

not bad! why do you suppose metaclasses don't have themselves as ancestors?
or perhaps put a better way - why DO normal classes?

this is great!

(please - somebody show me that it's wrong before i run wild with it ;-) )

kind regards.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
J

Joel VanderWerf

not bad! why do you suppose metaclasses don't have themselves as
ancestors?
or perhaps put a better way - why DO normal classes?

Mebbe because #ancestors shows the path that method lookup will follow,
_after_ checking for a singleton method.

irb(main):001:0> class << String; p ancestors; end
[Class, Module, Object, Kernel]
=> nil

There's no need to list the "metaclass" of String in the above, because
method lookup always starts with that object, if it exists, in case a
singleton method has been defined.

irb(main):002:0> class String; p ancestors; end
[String, Enumerable, Comparable, Object, Kernel]
=> nil

In this case, method lookup starts with the singleton class of the given
string (if one has been created), and then looks in the instance methods
of String, Enumerable, etc.
 
D

David A. Black

Hi --

jib:~/eg/ruby > cat a.rb
class Class
def inside_metaclass?
self.ancestors.first != self
end
end

class << self
p inside_metaclass? # true
end

Isn't that the case we talked about before where you clarified that
you didn't think it should be 'true' for singleton classes in general?
If not, them I'm retroactively confused again about the whole thread
and the use of terminology.


David
 
A

Ara.T.Howard

not bad! why do you suppose metaclasses don't have themselves as
ancestors?
or perhaps put a better way - why DO normal classes?

Mebbe because #ancestors shows the path that method lookup will follow,
_after_ checking for a singleton method.

irb(main):001:0> class << String; p ancestors; end
[Class, Module, Object, Kernel]
=> nil

There's no need to list the "metaclass" of String in the above, because
method lookup always starts with that object, if it exists, in case a
singleton method has been defined.

irb(main):002:0> class String; p ancestors; end
[String, Enumerable, Comparable, Object, Kernel]
=> nil

In this case, method lookup starts with the singleton class of the given
string (if one has been created), and then looks in the instance methods
of String, Enumerable, etc.

makes sense. bad name then. should be Class#search_path or someting...

cheers.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
A

Ara.T.Howard

Hi --



Isn't that the case we talked about before where you clarified that
you didn't think it should be 'true' for singleton classes in general?
If not, them I'm retroactively confused again about the whole thread
and the use of terminology.

lol. i've never heard of anyone being retroactively confused - but i'm sure i
am all the time. i think. maybe. i'm not sure.

anyways... this is the right __behaviour__ if not the right name. i'll change
it to inside_singleton? or something in my source.

too bad you can't edit usenet - anyone would think/know i'm a complete dolt if
reading this thread!

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
C

Carlos

[[email protected], 2005-05-05 00.15 CEST]
ha! first i noticed you made a typo (the first two lines are a no-op
without
another '&&') - and then i ran it anyhow. funny thing is it seems the last
line is all that's needed (if defined in Class)!

Yes, the #name thing was a leftover of some experiments trying to
distinguish between singleton classes of classes and the others
(unsuccessful). (This version was already in [ruby-talk:140408]...)
not bad! why do you suppose metaclasses don't have themselves as ancestors?
or perhaps put a better way - why DO normal classes?

I think Joel VanderWerf's explanation is the most likely.
 
D

David A. Black

Hi --

lol. i've never heard of anyone being retroactively confused - but i'm sure
i
am all the time. i think. maybe. i'm not sure.

anyways... this is the right __behaviour__ if not the right name. i'll
change
it to inside_singleton? or something in my source.

too bad you can't edit usenet - anyone would think/know i'm a complete dolt
if
reading this thread!

Well, I think I may be the dolt, since I always seem to be present
when these misunderstandings come up (me and Jim, me and you...) :)
But in fact I think it does come back to the terminology problem.
inside_singleton? is a little unclear, and inside_singleton_class? is
a bit lengthy Maybe the best name would be just: singleton_class?
So then you would have:

obj = Object.new
c = (class << obj; self; end)

c.singleton_class? # true

class << obj
singleton_class? # true
end

etc. This replaces the explicit "inside" term with the implicit fact
that, inside a class definition, self is the class -- so "insideness"
is already encapsulated in the self mechanism.

(At some point I'll try to go back and look at the examples and figure
out whether I have anything substantive to say about the whole idea
:)


David
 
T

Trans

anyways... this is the right __behaviour__ if not the right name. i'll change
it to inside_singleton? or something in my source.

Are you completely sure? What about these?

class A
# class methods
def self.ic_class
idioclass?
end
class << self
def ic_class2
idioclass?
end
end
# instance method
def ic_instance
idioclass?
end
end

T.
 
A

Austin Ziegler

Ara.T.Howard said:
this is very useful for meta-programming:

jib:~/eg/ruby > cat a.rb
class Object
def inside_metaclass? [...]

i believe the implementaion is correct iff the following statement is true:

all meta-classes descend from the meta-class of Object.

the statement is[...]

...true.

Please stop posting your incorrect statements, Ilias. Just because you
don't understand it doesn't mean that something is false

-austin
 
I

Ilias Lazaridis

Austin said:
Ara.T.Howard said:
this is very useful for meta-programming:

jib:~/eg/ruby > cat a.rb
class Object
def inside_metaclass? [...]

i believe the implementaion is correct iff the following statement is true:

all meta-classes descend from the meta-class of Object.

the statement is[...]

..true.

Please stop posting your incorrect statements, Ilias. Just because you
don't understand it doesn't mean that something is false

A "class" is instantiated to 0..n objects.
A "singleton class" is instantiated to 0..1 object
A "metaclass" is instantiated to 0..n Class Objects

Ruby has no metaclasses.

No one can insist on this.

If it's Mr. Austin Ziegler of Mr. Y. Matsumoto.

-

The correct term would be "exclusive object" (or something similar, but
_not_ metaclass, which has a specific meaning):

The diagramm (V1.3) demonstrates this.

http://lazaridis.com/case/lang/ruby

-

So, readers can now decide who's right and who's false.

..
 
H

Hal Fulton

Ilias said:
A "singleton class" is instantiated to 0..1 object

You're thinking of the Singleton pattern, which deals
with a class which can only be instantiated once,
resulting in a single object.

The term "singleton" simply means "something which is
unique or occurs only once."

The term "singleton" is used in the Ruby community to
mean several things:

- an object of a class which can only be instantiated
once (Singleton Pattern)
- a method that is unique to its object, rather than
originating in the class of the object
- an object containing methods that are unique to that
object, i.e., containing singleton methods

When we say "singleton class," we are not really saying
"a class which is a singleton."

In English, the adjective does not always modify the noun
in the same way. "Human Services" means services FOR
humans; a "Reptile Zoo" is a zoo OF reptiles (not one
that we intend reptiles to visit and pay admission).

We use the term "singleton class" not to signify "a class
that is a singleton," but rather to signify "a class where
we store the singleton methods."

To add to the confusion, a class in Ruby is an object. So
when is a class anything *but* a singleton? Is there more
than one occurrence of Fixnum in Ruby? I suppose we could
do Fixnum.dup and there would be.

In short, the Ruby community's usage is not 100% in line
with the rest of the CS community. But that is OK, because
1) even the CS community at large does use terms with 100%
consistency, and 2) we are using terms for concepts that do
not exist in most other OO languages.


Hal
 
I

Ilias Lazaridis

Hal said:
You're thinking of the Singleton pattern, which deals
with a class which can only be instantiated once,
resulting in a single object.

=> resulting in a "singleton object"
The term "singleton" simply means "something which is
unique or occurs only once."

of ocurse.
The term "singleton" is used in the Ruby community to
mean several things:

- an object of a class which can only be instantiated
once (Singleton Pattern)
ok

- a method that is unique to its object, rather than
originating in the class of the object

=> singleton method
- an object containing methods that are unique to that
object, i.e., containing singleton methods
[...] - (attemp to justify duplicate meaning of terminology)

"Singleton Class" is a defined terminology.

I will not use it, simply because a confused language-designer has
defined it that way.

[btw: the central point of this thread is the false usage of the term
"metaclass"]

..
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: [RCR] Object#inside_metaclass?"

|"singleton class" has already a meaning within OOP.
|like this: "a class which has only one instance"

According to the Design Pattern book, right?

Interestingly, I started to use the term before the book was published
in 1995. Sad coincidence.

matz.
 
I

Ilias Lazaridis

Yukihiro said:
Hi,

In message "Re: [RCR] Object#inside_metaclass?"

|"singleton class" has already a meaning within OOP.
|like this: "a class which has only one instance"

According to the Design Pattern book, right?

I don't know this book.
Interestingly, I started to use the term before the book was published
in 1995. Sad coincidence.

I understand.

But makes it any sense to insist on that?

Or makes it sense to change the terminology, thus it doesn't conflict
with this:

http://www.google.com/search?q=singleton+class

ensuring this way a simpler teach-in to ruby?

Please act, and initialize a terminology change.

-

If you like, contact me via private email thus we can discuss the issue
non-public.

..
 

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

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,124
Latest member
JuniorPell
Top