[#1026] Is this a bug? — Dave Thomas <Dave@...>

18 messages 2000/01/03

[#1084] Infinite loop — Dave Thomas <Dave@...>

17 messages 2000/01/11

[#1104] The value of while... — Dave Thomas <Dave@...>

24 messages 2000/01/11

[ruby-talk:01156] Re: Factory of classes

From: matz@... (Yukihiro Matsumoto)
Date: 2000-01-18 00:07:20 UTC
List: ruby-talk #1156
In message "[ruby-talk:01137] Re: Factory of classes"
    on 00/01/14, Yukihiro Matsumoto <matz@netlab.co.jp> writes:

||class Factory
||    def new(name)
||        {|name| class name def new @var = nil end end}(name)
||    end
||end
|
|How about the code like this.
|
|  class Factory
|    class <<Factory
|      alias orig_new new
|      def new
|	klass = Class.new(self)
|	def klass.new
|	  orig_new
|	end
|	klass
|      end
|    end
|  end
|
|  Person = Factory.new
|  John = Person.new

Let me explain this code more.

  class Factory                 # defining new class, the Factory
    class <<Factory             # defining Factory's attribute 
                                # (e.g. class method etc.)

      alias orig_new new        # save original class method new
                                # because it's only way to create instance.

      def new                   # re-define class method new
	klass = Class.new(self) # creating new unnamed class,
                                # which is subclass of Factory.

	def klass.new           # restore back original new
	  orig_new              # to create an instance.
	end
	klass                   # new class should be a return value.
      end
    end
  end

  Person = Factory.new          # create an unnamed class .
  John = Person.new             # create an instance by restored `new'.

The syntax

  class <<obj
  end

is singleton class definition.  The attributes defined in the body
belong to the certain object.  It is used for defining singleton
methods, or class methods.

||So, any ideas? and then, how can I get delayed evaluation of variables (or metavariables, depending how you see it) so the compiler will let the  closure expand on run-time (if it is possible at all...)
|
|In the code above, I didn't use any runtime expansion.  You can always
|use eval for that purpose (with your own risk & responsibility).

Here's an example:

  class Factory
    def Factory.create(name)
      eval "class #{name}; def initialize; @var = nil; end; end; #{name}"
    end
  end
  Person = Factory.create("Person")
  John = Person.new

Using `create' for simplicity, though you can override `new' by same
technique used by the former example.

							matz.

In This Thread

Prev Next