About class methods

Martin DeMello wrote:

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.

So, this means you lose the functionality of a? I thought the whole
point was to extend a. The tutorial
(http://www.rubygarden.org/ruby?SingletonTutorial\) actually doesn't
mention whether it is super or sub, i just assumed sub. I suppose
whether it was super or sub really doesn't matter except in what you
would be referencing by 'self' or 'super' in the added code (i.e., if
you are correct, then doing self at class scope level would allow you to
access the super class, or doing self at instance scope (in the new
code) would reference an instance of the super class. Of course, if you
used super in that context, it would reference the original class'
grandparent. Are you sure this is how it works? The tutorial doesn't
do any of the things I just mentioned, so it can't answer this question.

Thanks,
--J

···

--
Posted via http://www.ruby-forum.com/\.

Martin DeMello wrote:

···

"jonathan <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu>" <zjll9@imail.etsu.edu> 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

How about this old chestnut, which I frankly don't understand:

http://onestepback.org/images/rubyobjects.png

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

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

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

···

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

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.

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

···

On 2005.12.11 10:34, "jonathan <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu>" <zjll9@imail.etsu.edu> wrote:

Hi --

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.

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.

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

···

On Sun, 11 Dec 2005, jonathan <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> wrote:

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", forthcoming from Manning Publications, April 2006!

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

--J

···

--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/\.

ruby-ml wrote:

···

On 2005.12.11 10:34, "jonathan <zjll9@imail.etsu.edu> > <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu>" > <zjll9@imail.etsu.edu> 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

--
Posted via http://www.ruby-forum.com/\.

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

···

--
Posted via http://www.ruby-forum.com/\.

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 <zjll9@imail.etsu.edu> <zjll9@ima wrote:

(I think it is also known as
metaprogramming).

--
Posted via http://www.ruby-forum.com/\.

ruby-ml 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

···

jonathan leonard <zjll9@imail.etsu.edu> <zjll9@ima wrote:

On 2005.12.11 10:34, "jonathan <zjll9@imail.etsu.edu> >> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu> <zjll9@imail.etsu.edu>" >> <zjll9@imail.etsu.edu> wrote:

--
Posted via http://www.ruby-forum.com/\.

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

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

···

On 2005.12.12 13:07, "jonathan <zjll9@imail.etsu.edu> <zjll9@ima" <zjll9@imail.etsu.edu> wrote:

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 Gray II

···

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

jonathan leonard <zjll9@imail.etsu.edu> <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.

Eero Saynatkari 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

···

--
Posted via http://www.ruby-forum.com/\.

jonathan leonard wrote:

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

I personally think the idiom is a bit suspect but it could
just be I have not come across the need for it :slight_smile: The above
merely illustrates that it is quite possible to do that in
ruby; however, another way might lead to a better design.

(Generally, any types of factories are simple in ruby and
the whole duck-typing thing helps, too.)

--J

E

···

--
Posted via http://www.ruby-forum.com/\.

Eero Saynatkari wrote:

Why is the code above unadvisable?

I personally think the idiom is a bit suspect but it could
just be I have not come across the need for it :slight_smile: The above
merely illustrates that it is quite possible to do that in
ruby; however, another way might lead to a better design.

(Generally, any types of factories are simple in ruby and
the whole duck-typing thing helps, too.)

I don't really see how duck-typing is relevant, but I would assume that
the idiom used above (i.e., 'const_set', 'class_eval', and
'define_method') could be done in an extension factory (rather than
procedurally as above). In other words, you might have a factory called
JumpExtensionFactory which could create any object that can jump (e.g.,
people, animals, monsters, etc.) from a non-jumping object say in a
video game model.

I suppose it would have to calculate the maximum jump height and length
based on other statistics such as leg strength, weight, etc. (which
would presumably have to be attributes the object already has or can
acquire) and the actual jump height and length based on run-time
attributes such as velocity and input force. That is the purpose I can
see for this sort of thing. Is that what you mean by utilizing
factories?

The only real problem I see with this is you really wouldn't want to
create a new object, but rather extend the original one. In other
words, after a type learns to jump, then all objects of that type should
be able to jump (so there's no need to distinguish from a non-jumping
version and the jumping version). So, actually, I would call it an
JumpExtender or a JumpTeacher (instead of JumpExtensionFactory).

(Thinking out loud here). But, hopefully we're closer to the same page
now.

--J

···

--
Posted via http://www.ruby-forum.com/\.