From: Clifford Heath Date: 2007-01-31T15:30:13+09:00 Subject: Re: Tricks with method as superclass --------------000904090400060605020907 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit ara.t.howard@noaa.gov wrote: > # Class.new(Foo).instance_eval <<-END > Class.new(Foo).module_eval <<-END Thanks Ara - super-quick response too! Caught out by the singleton, which I didn't expect to find on a Class instance. Here's a complete example that shows most of what's possible, assuming the attachment comes through. Clifford Heath. --------------000904090400060605020907 Content-Type: text/plain; name="superclass-method.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="superclass-method.rb" # Start with a real base class class Base def initialize(*args, &block) # puts "Base::initialize #{args.inspect} &#{block.inspect}" print("Base::") block.call(*args) if block end # Return a new anonymous class derived from Base, with class variables and initialize def self.augment(*args, &block) Class.new(self).class_eval { @@_base_args = args @@_base_block = block # puts "new class is #{self.object_id} #{args.inspect} &#{block.inspect}" def initialize(*args, &block) # puts "Constructing instance with base #{@@_base_args.inspect} &#{@@_base_block.inspect}, instance #{args.inspect} &#{block.inspect}" @@_base_block.call(*@@_base_args) if @@_base_block super(*args, &block) end self } end end # Here's the method used to create the custom base class: def Base(*args, &block) puts "Defining funky magic with #{args.inspect} &#{block.inspect}" Base.augment(*args, &block) end # A subclass with neither args nor block: class Sub0 < Base end Sub0.new { puts "No augmented class, use Base alone" } # A subclass with just args: class Sub1 < Base("arg1") end Sub1.new("Thinking...") { |*args| puts "#{args.inspect}: Ok" } # A subclass with just a block: class Sub2 < Base { print "Hi" } end Sub2.new { puts " there!" } # A subclass with args and a block: class Sub3 < Base("arg1", "arg2") { |*args| puts "#{args.inspect}: getting things all ready for you..." } def initialize(*args, &block) super(*args, &block) puts "#{args.inspect}: fun for all the family!" end end Sub3.new("sub1", "sub2") { |*args| puts "#{args.inspect}: still working" } --------------000904090400060605020907--