On Sat, 14 Jun 2003, Markus Jais wrote:

> hello
>
> I would like to create classes dynamically and also the name of the class
>
> somethink like that
>
> cl  = Class.new("Eagle")  # does not work
>
> bird = Eagle.new
> bird.fly()
>
> can this be done ? I want many classes to be created and the names come from
> config files or the command line

here are some ideas:

~ > cat bird.rb
#!/usr/bin/env ruby

birdname = ARGV[0] || 'Eagle'

# this allows a class with attributes only...
attributes = :wing_span, :age
Birdclass = Struct.new birdname, *attributes
bird = Birdclass.new
bird.wing_span = 42.0
# you could then add methods to the object like this:
class << bird
  def fly; 'fly'; end
end
p bird.fly


# or perhaps it'd be better to add it to the class up front
module BirdModule
  def fly; 'Fly'; end
end
Birdclass2 = Struct.new birdname, *attributes
Birdclass2.send :include, BirdModule
bird = Birdclass2.new
bird.wing_span = 42.0
p bird.fly


# alternatively, you could create libfiles and require them
# this could be really helpful for debugging purposes and could
# also allow caching of classes between invocations...

module Bird; BIRD_CLASSES = {}; end

classdef = <<-'ruby'
module Bird
  class %s
    attr_accessor :wing_span
    attr_accessor :age
    def fly; 'FLY'; end
  end

  BIRD_CLASSES['%s'] = %s
end
ruby

lib = './birdlib.rb'
open(lib,'w'){|f| f.puts(classdef % [birdname, birdname, birdname])}
require lib
birdclass = Bird::BIRD_CLASSES[birdname]
bird = birdclass.new
bird.wing_span = 42.0
p bird.fly


~ > ruby bird.rb
"fly"
"Fly"
"FLY"



i like the last one best for it's debugging, testing, and caching
capabilities...  any method which creates a class dynamically is hard to test -
this way you could test any of the created classes using the cached libs...

-a
--
  ====================================
  | Ara Howard
  | NOAA Forecast Systems Laboratory
  | Information and Technology Services
  | Data Systems Group
  | R/FST 325 Broadway
  | Boulder, CO 80305-3328
  | Email: ara.t.howard / noaa.gov
  | Phone:  303-497-7238
  | Fax:    303-497-7259
  | ~ > ruby -e 'p(%.\x2d\x29..intern)'
  ====================================