About class methods

Hi –

On Sat, 10 Dec 2005, jonathan [email protected]
[email protected] [email protected] wrote:

Hmm… Ok. But, with Ruby, you can still dynamically create subclasses
that aren’t singletons and extend them as well as instanciate instances
of them, right? That would provide the flexibility I was referring to
above, but I suppose it would require typing quite a few more
characters. So do I understand correctly that Matz designed the whole
singleton creation mechanism ( << ) as a shorthand for doing more
long-winded dynamic creation/enhancing?

The starting-point of the whole thing is the principle that objects
can be individually extended. Two instances of MyClass, for example,
begin life with the same capabilities (methods), but during their
lives can diverge:

class MyClass
end

a = MyClass.new
b = MyClass.new

def a.x
end

def b.y
end

The singleton class mechanism is just a way to store those “extra”
methods. The methods written for a (namely, “x”) go in a’s singleton
class; those for b, in b’s; etc. These classes are created
automatically when they are needed.

If you want to open a class definition block for an object’s singleton
class, you use the class keyword, plus “<< obj”. This special syntax
is necessary because singleton classes are anonymous. Other than
that, it’s very much like doing “class C”.

It’s all very simple and elegant, isn’t it? :slight_smile:

David


David A. Black
[email protected]

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!

On Dec 10, 2005, at 8:34 PM, jonathan wrote:

Hmm. Ok, so there really is no singleton class for Myclass? In other
words, must the singleton always be associated with an instance and
not
a class?

In Ruby, a class is an instance. Specifically, a class is an instance
of the class Class. So, yes, you can reference the singleton object
of a class:

class <<Array
end

More often it is done like this though:

class Array
  class <<self
    # instance methods defined here will be
         # for the object Array (which happens to be a class)
    # so these methods become 'class methods' for Array
  end
end

Alternatively you can do it like this:

def Array.class_method1
  # an instance specific method
  # in this case the instance is the class object Array
end
        end }

eval( code )

extend_class( Myclass )
x = Myclass_extension.new
x.new_method1
y = Myclass_extension.new
y.new_method1

I’m not sure what you are getting at here.

Myclass.class is the particular object Class. Because
all class objects are instances of Class.

#{some_class.class}_extension

ends up being the string

Class_extension

because Class.to_s is the string ‘Class’.

If you want to subclass and add methods just do it:

class Myclass
end

class Subclass < Myclass
def new_method1
end
end

x = Subclass.new
y = Subclass.new
x.new_method1
y.new_method1

gwtmp01 wrote:

extend_class( Myclass )
x = Myclass_extension.new
x.new_method1
y = Myclass_extension.new
y.new_method1

I’m not sure what you are getting at here.

Myclass.class is the particular object Class. Because
all class objects are instances of Class.

#{some_class.class}_extension

ends up being the string

Class_extension

because Class.to_s is the string ‘Class’.

Oops. It should have been #{some_class}. The whole point of that was
so that I could have code that writes code (dynamically) based on states
of other parts of the program (I think it is also known as
metaprogramming). Of course, with that simple example I posted, it
wouldn’t make much sense. It seems like this sort of thing would be
very useful for artificial intelligence (i.e., learning).

On the class singleton example you posted: that’s very neat. Now, I
think my understanding of these sort of singletons is complete. :slight_smile:

–J

dblack wrote:

Hmm… Ok. But, with Ruby, you can still dynamically create subclasses
that aren’t singletons and extend them as well as instanciate instances
of them, right? That would provide the flexibility I was referring to
above, but I suppose it would require typing quite a few more
characters. So do I understand correctly that Matz designed the whole
singleton creation mechanism ( << ) as a shorthand for doing more
long-winded dynamic creation/enhancing?

The starting-point of the whole thing is the principle that objects
can be individually extended. Two instances of MyClass, for example,
begin life with the same capabilities (methods), but during their
lives can diverge:

class MyClass
end

a = MyClass.new
b = MyClass.new

def a.x
end

def b.y
end

The singleton class mechanism is just a way to store those “extra”
methods. The methods written for a (namely, “x”) go in a’s singleton
class; those for b, in b’s; etc. These classes are created
automatically when they are needed.

Hmm. Ok, so there really is no singleton class for Myclass? In other
words, must the singleton always be associated with an instance and not
a class?

If you want to open a class definition block for an object’s singleton
class, you use the class keyword, plus “<< obj”. This special syntax
is necessary because singleton classes are anonymous. Other than
that, it’s very much like doing “class C”.

It’s all very simple and elegant, isn’t it? :slight_smile:

Yea. That is cool, but can you still do something like this:

class Myclass
end

def extend_class( some_class )
code = %{ class #{some_class.class}_extension < #{some_class.class}
def new_method1
end

end }
eval( code )

extend_class( Myclass )
x = Myclass_extension.new
x.new_method1
y = Myclass_extension.new
y.new_method1

Some variation of this (where the extended class is named uniquely)
should allow infinitely many extended subclasses and also allow
non-singleton (i.e., many) instances of the subclasses.

Of course, I suppose you could start with x and y as instances of the
base class and add the new_method’s to each of them just as easily (and
with probably less typing). So, would there ever be a reason to do
something like I wrote above?

–J

On 2005.12.11 10:34, “jonathan [email protected]
[email protected] [email protected] [email protected]
[email protected] wrote:

can be individually extended. Two instances of MyClass, for example,
end
words, must the singleton always be associated with an instance and not

        end }

non-singleton (i.e., many) instances of the subclasses.
Typically, if I understand you correctly, you could just use this
idiom (unless you want to just eval the whole thing):

Classes are constants

| Inherit MyClass

| | We can use blocks

| | |

V V V

MyClassExtension = Class.new(MyClass) {
def self.some_method()
# …
end

                   def some_method()
                     # ...
                   end
                 }

Of course, I suppose you could start with x and y as instances of the
base class and add the new_method’s to each of them just as easily (and
with probably less typing). So, would there ever be a reason to do
something like I wrote above?

–J

E

ruby-ml wrote:

On 2005.12.11 10:34, “jonathan [email protected]
[email protected] [email protected] [email protected]
[email protected] wrote:

can be individually extended. Two instances of MyClass, for example,
end
words, must the singleton always be associated with an instance and not

        end }

non-singleton (i.e., many) instances of the subclasses.
Typically, if I understand you correctly, you could just use this
idiom (unless you want to just eval the whole thing):

Classes are constants

| Inherit MyClass

| | We can use blocks

| | |

V V V

MyClassExtension = Class.new(MyClass) {
def self.some_method()
# …
end

                   def some_method()
                     # ...
                   end
                 }

Oooh. That’s cool! In the case I was envisioning, I would want to eval
the whole thing (so that classes could be extended dynamically at
run-time).

–J

jonathan leonard [email protected] <zjll9@ima wrote:

(I think it is also known as
metaprogramming).

Actually, according to wikipedia, metaprogramming involves only rewrites
done at compile time and not run-time (such as lex or yacc, which
generate code). So, I guess this would simply be ‘self-modifying’ code.

–J

jonathan leonard [email protected] <zjll9@ima wrote:

ruby-ml wrote:

On 2005.12.11 10:34, “jonathan [email protected]
[email protected] [email protected] [email protected]
[email protected] wrote:

can be individually extended. Two instances of MyClass, for example,
end
words, must the singleton always be associated with an instance and not

        end }

non-singleton (i.e., many) instances of the subclasses.
Typically, if I understand you correctly, you could just use this
idiom (unless you want to just eval the whole thing):

Classes are constants

| Inherit MyClass

| | We can use blocks

| | |

V V V

MyClassExtension = Class.new(MyClass) {
def self.some_method()
# …
end

                   def some_method()
                     # ...
                   end
                 }

Oooh. That’s cool! In the case I was envisioning, I would want to eval
the whole thing (so that classes could be extended dynamically at
run-time).

Just to be clear (I think you have the right idea, but for the
benefit of any future ruby miners), you can use the above
construct dynamically at runtime.

If you are doing a lot of dynamic method naming and such
(a proposition of debateable merit as you would have to
#send all your messages), it may be easier to use strings
in conjunction with one of #(class|module|instance)_eval.

–J

E

On Dec 10, 2005, at 11:16 PM, jonathan leonard wrote:

jonathan leonard [email protected] <zjll9@ima wrote:

(I think it is also known as
metaprogramming).

Actually, according to wikipedia, metaprogramming involves only
rewrites
done at compile time and not run-time (such as lex or yacc, which
generate code). So, I guess this would simply be ‘self-modifying’
code.

That’s not how we generally use it in the Ruby community, but keep in
mind that Ruby greatly blurs the compile-time, run-time distinction.

My buddy calls Unit Tests, Ruby’s compile-time error checking. Hard
to argue with that. :wink:

James Edward G. II

[email protected] wrote:

But the whole thing may indeed
become non-class-based. I’m not sure what that would entail. I kind
of think that if it were something other than a class, one would end
up longing for a “class interface” to it, and then it might as well be
a class…

I tend to agree with you. While on the surface it may seem simpler
without the class, I think it actually ends being more complicated. I
think the same holds true for aop wraps --another reason to favor of
cuts over (or as a foundation for) the proposed hooks.

T.

Hi –

On Sun, 11 Dec 2005, jonathan [email protected]
[email protected] [email protected] [email protected]
wrote:

dblack wrote:

The singleton class mechanism is just a way to store those “extra”
methods. The methods written for a (namely, “x”) go in a’s singleton
class; those for b, in b’s; etc. These classes are created
automatically when they are needed.

Hmm. Ok, so there really is no singleton class for Myclass? In other
words, must the singleton always be associated with an instance and not
a class?

Every object (almost) can have a singleton class, including Class
objects.

extend_class( Myclass )
x = Myclass_extension.new
x.new_method1
y = Myclass_extension.new
y.new_method1

Some variation of this (where the extended class is named uniquely)
should allow infinitely many extended subclasses and also allow
non-singleton (i.e., many) instances of the subclasses.

There are easier ways, such as (I think someone else pointed out)
Class.new(superclass). Using eval is a stretch; in fact, I’m fairly
confident in saying that it’s almost a certain sign that you’re doing
something which can be done a cleaner way, or that perhaps needs to be
rethought entirely.

Anyway – a non-eval version of what you’ve got above might be
something like:

class MyClass
end

def extend_class(classname)
ex = Object.const_set(classname.to_s + “_extension”, Class.new)
ex.class_eval do
def new_method1
puts “new method”
end
end
end

extend_class(MyClass)
x = MyClass_extension.new
x.new_method1

Of course, I suppose you could start with x and y as instances of the
base class and add the new_method’s to each of them just as easily (and
with probably less typing). So, would there ever be a reason to do
something like I wrote above?

Probably not :slight_smile: But it’s good to learn all of these permutations, I
think.

David


David A. Black
[email protected]

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!

unknown wrote:

class MyClass
end

def extend_class(classname)
ex = Object.const_set(classname.to_s + “_extension”, Class.new)
ex.class_eval do
def new_method1
puts “new method”
end
end
end

extend_class(MyClass)
x = MyClass_extension.new
x.new_method1

Oh. That’s a neat way of doing it. Would the code below also work in
order to support a dynamic method name?

class MyClass
end

def extend_class(classname, methodname)
  ex = Object.const_set(classname.to_s + "_extension", Class.new)
  ex.class_eval %{
     def #(methodname)
       puts "new method"
     end }
   end
end

–J

I’m curious why “class method” is being avoided? It certainly seems
accurate and matches the use of class methods by languages such as
Smalltalk
and Objective-C.

On 2005.12.12 13:07, “jonathan [email protected] <zjll9@ima”
[email protected] wrote:

      puts "new method"

order to support a dynamic method name?
end
end

Well, there is always define_method:

This code for illustrative purposes only. This is unadvisable.

class Class
def extend_by(method_name, &block)
o = Object.const_set(“#{self.name}Extension”, Class.new(self))
o.class_eval {
define_method(method_name, &block)
}
o
end
end

class Foo
end

Extension = Foo.extend_by(‘quux’) { puts “Hello from quux!” }
Extension.new.quux

–J

E

Mark E. wrote:

I’m curious why “class method” is being avoided? It certainly seems
accurate and matches the use of class methods by languages such as Smalltalk
and Objective-C.

I think “class method” is used in our community, but it is considered
a special case – it’s just a singleton method on an object which
happens
to be a class. A singleton method on an object which isn’t a class –
well, that obviously isn’t a class method.

Hal

“jonathan [email protected] [email protected]
[email protected][email protected] wrote:

Hmm… Ok. But, with Ruby, you can still dynamically create subclasses
that aren’t singletons and extend them as well as instanciate instances
of them, right? That would provide the flexibility I was referring to
above, but I suppose it would require typing quite a few more
characters. So do I understand correctly that Matz designed the whole
singleton creation mechanism ( << ) as a shorthand for doing more
long-winded dynamic creation/enhancing?

It’s not a subclass, it’s an anonymous proxy superclass. It goes into
the inheritance chain between the object it extends and the class that
object derived from, like so (assume a is a String):

[String] — [class << a] — [a]

Since ruby doesn’t have multiple inheritance, you can see why there can
(and need!) only be a single proxy superclass.

martin

On 2005.12.12 17:07, Chad P. [email protected] wrote:

well, that obviously isn’t a class method.

By the way . . . has anyone considered a name like “singular”? What
about “ad lib” instead of “ad hoc”?

I’ve gotta say, though, that I’m partial to the descriptor “eigen”.

I advocate “pouch” :slight_smile:

In any case, it might be wise to hold some sort of a poll (or perhaps
Matz can be coerced to pick the one he prefers) because I have noticed
a trend of different groups using different terms for the same thing
which in turn has caused some confusion about the feature in general.

E

On Mon, Dec 12, 2005 at 03:30:50PM +0900, Hal F. wrote:

Mark E. wrote:

I’m curious why “class method” is being avoided? It certainly seems
accurate and matches the use of class methods by languages such as
Smalltalk
and Objective-C.

I think “class method” is used in our community, but it is considered
a special case – it’s just a singleton method on an object which happens
to be a class. A singleton method on an object which isn’t a class –
well, that obviously isn’t a class method.

By the way . . . has anyone considered a name like “singular”? What
about “ad lib” instead of “ad hoc”?

I’ve gotta say, though, that I’m partial to the descriptor “eigen”.


Chad P. [ CCD CopyWrite | http://ccd.apotheon.org ]

unix virus: If you’re using a unixlike OS, please forward
this to 20 others and erase your system partition.

Eero S. wrote:

Well, there is always define_method:

This code for illustrative purposes only. This is unadvisable.

class Class
def extend_by(method_name, &block)
o = Object.const_set("#{self.name}Extension", Class.new(self))
o.class_eval {
define_method(method_name, &block)
}
o
end
end

class Foo
end

Extension = Foo.extend_by(‘quux’) { puts “Hello from quux!” }
Extension.new.quux

Why is the code above unadvisable?

–J

Oops. Nevermind the part about losing functionality. However, I think
the discussion of self/super still applies.

–J