On May 6, 2006, at 4:31 PM, Eli Bendersky wrote:

> Logan Capaldo wrote:
>> On May 6, 2006, at 4:10 PM, Bira wrote:
>>
>>>>
>>> I think I still have a long way to go before I can write a decent,
>>> Ruby-ish example :). This one is a little beyond my ability to
>>> understand at a glance...
>>>
>>> What happens when I call Database.new(some_file) ? In which order to
>>> the "new" and "initialize" methods get called?
>>>
>> Basically new calls initialize, and then returns the instance of the
>> object. The normal implementation of new would look something like:
>>
>> class Class
>>    def new(*args, &block)
>>      obj = self.allocate
>>      obj.initialize(*args, &block)
>>      obj
>>    end
>> end
>>
>> My new does some extra work by defining the Record class based on
>> some info in the file. There's a big problem with my code though and
>> it's called Only one database per program!. Or at least only one at a
>> time
>>
>> e.g.
>>
>> db1 = Database.new(file1)
>> db2 = Database.new(file2)
>>
>> if file2 has a different record format than file1, it's going to
>> seriously mess up any interactions with db1. An alternative method
>> would be of course to do something like
>>
>> class Database
>>    def initialize(file)
>>        @Record =  Struct.new(...)
>>        ...
>>    end
>> end
>
> This "only one database per program" problem you refer to is  
> actually a
> problem with my design. I wonder how to go around it.
>
> I do want to be able to have two different Databases that use  
> different
> Record formats, but still be able to access the fields via Struct-like
> accessors.
>
> I realize that with this design it's not possible, since
> Database::Record refers only to a single class, not to different
> classes.
>
> -- 
> Posted via http://www.ruby-forum.com/.
>

Just go up one level, e.g.

module Database # Not really a class, more of a class factory
   def self.new(file)
       db_klass = Class.new
       db_klass.class_eval do
          record_format = parse_format(file)
          self.const_set('Record', Struct.new(*record_format))
          @@db_file = file
          def initialize
            @file = @@db_file
            ...
          end
       end
       db_klass
   end
end

SongDatabase = Database.new('songs.txt')

song_db = SongDatabase.new

# do stuff with song_db