Clifford Heath
1/31/2007 6:26:00 AM
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.
# 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"
}