Forum: Ruby self.new and initialize ( was Re: Creating sub-classes using

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Bira (Guest)
on 2006-05-07 00:11
(Received via mailing list)
On 5/6/06, Logan C. <removed_email_address@domain.invalid> wrote:

>       @records = []
>       read_each_record_in_file(file) do |record_data|
>            record = Database::Record.new
>            extract_record_data_into(record_data, record)
>            @records << record
>       end
>   end
> end

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?
Logan C. (Guest)
on 2006-05-07 00:26
(Received via mailing list)
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
Eli B. (Guest)
on 2006-05-07 00:31
Logan C. 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.
Logan C. (Guest)
on 2006-05-07 01:02
(Received via mailing list)
On May 6, 2006, at 4:31 PM, Eli B. wrote:

>>>
>>
>> if file2 has a different record format than file1, it's going to
> This "only one database per program" problem you refer to is
> 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
This topic is locked and can not be replied to.