On Thu, 1 May 2003, Simon Vandemoortele wrote:

> > If you'd like to pass around an object and be sure it'll never get
> > altered by its reciever, then a Contact/MutableContact pair seems
> > unavoidable.
>
> Indeed.
>
>
> Simon
>
>
>
> PS: As we evolve in this discussion I find myself frightened by the
> complexity of something that, at first, seemed a rather trivial design.
> It is starting to look as if the effort required to make the Addressbook
> I am implementing *really* safe, is more than what I am willing to put
> into it ... especially since there is a chance it will never be used by
> any other client than the one I am designing. How does one tell if one
> is too lazy too think out a decent (future-proof) design or if one is
> sinning against the YAGNI I idiom ?


simon-

perhaps you've already considered this, but why not simply use an embedded
database (guy's bdb wrapper is great) - this neatly solves the entire problem
of mutable/not-mutable since query results can be mapped to objects that the
client can tweak to their heart's content, and also makes the entire design
trivial where referential integrity is concerned.  just thought i'd through
that out there...

----CUT----
#!/usr/bin/env ruby
require 'sqlite'
Contact = Struct.new('Contact', :name, :number, :address)

class AddressBook
  def initialize args=nil
    db = args && args[:db] || 'addressbook.db'
    create = args && args[:create]
    @db = SQLite.new(db)
    if create
      sql = <<-sql
	create table addressbook (
	  name, number, address,
	  primary key (name)
	);
      sql
      @db.exec (sql)
    end
  end
  def add_contact contact
    values = contact.values.map{|v| "'#{v}'"}.join(',')
    sql = <<-sql
      insert into addressbook
      values (#{values});
    sql
    @db.exec (sql)
  end
  def get_contact name
    sql = <<-sql
      select * from addressbook
      where name = '#{name}' limit 1;
    sql
    fieldnames, values = @db.exec (sql)
    Contact.new *values
  end
end

ab = AddressBook.new :db => 'ab.db', :create => true
c = Contact.new 'bob', '303.455.2099', '42 Answer St.'
ab.add_contact c
mutable = ab.get_contact 'bob'
mutable.name = 'joe'

p mutable
p ab.get_contact 'bob'
----CUT----

~/eg/ruby/sqlite > ruby ./addressbook.rb
#<Struct::Contact name="joe", number="303.455.2099", address="42 Answer St.">
#<Struct::Contact name="bob", number="303.455.2099", address="42 Answer St.">


-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 / fsl.noaa.gov
  | Phone:  303-497-7238
  | Fax:    303-497-7259
  ====================================