On Wed, 30 Apr 2003 at 18:07 GMT, Dave Thomas wrote: > Is a Contact that you return as the result of a search(say) the same > type of thing that you use to create or edit a new entry? Yes. > You assumption is that they are (basically) the same thing, but perhaps > you might want to rethink that. They don't seem to share the same > methods. Maybe you need two classes: Contact and MutableContact. Regular > Contact classes have methods that let them be examined but not altered. > MutableContacts allow change. If needed by your application, class > Contact could include a #to_matuable method that returned a MutableContact. Hmmm. I never thought about that, mainly because it requires creating two types of contacts that will hold _exactly_ the same data. I will take it into consideration. Simon PS: When I have complex problems like this one, I have a habit of writing them out as a post to clarify my thinking. I often let it simmer a while and rewrite it before I post. This time however I inadvertently posted the message before I got a chance to rewrite it :>. (I canceled the post immediately but it seems it did get to ruby-talk.) For those of you who are interested: this is what I *was* going to post before I got Dave's reply: <snip> _Goal:_ An Addressbook class that can be reused. _Initial Design and shortcomings:_ The way I see it, an addressbook is merely a (smart) container for contacts. It is responsible for loading, storing, managing (adding, deleting) and saving the contacts. Thus, the interface could be something like: Addressbook |- open(filename) |- addContact(contact) |- getContact(name) `- removeContact(name) Contact |-setName |-getName |-setAge |-getAge |-... This approach provides a lot of flexibility - you can change a contact with a one-liner: myAddressbook.getContact('Simon Vandemoortele').setAge(25). However, it leaves the content of addressbook (the contacts) freely editable by everyone. I hope we all agree to the fact that this is a serious limitation to the interface. Because someone can change a contact without the addressbook noticing, the addressbook cannot enforce any invariant that depends on it's contacts content. i.e.: it can't enforce a no-two-entries-with-the-same-name policy. Nor can we decide to implement the addressbook as a sorted Array anymore. _Alternative designs:_ I am told by learned colleagues that the OO take on this kind of problems is to introduce *immutability*. [1] The classical way to do this is by making the interface immutable (no writer methods). So 'setAge' would not change the contact's name but instead create a copy of the instance with an updated age attribute: myContact = myAddressbook.getContact('Simon Vandemoortele') myContact = myContact.setAge(25) myAddressbook.updateContact(myContact) This can be quite cumbersome. [2] In Ruby there might be a different way to do it: require that all contacts submitted to the addressbook be frozen. That way you can enforce immutability without losing the convenience of attribute writers on Contact. The drawback I see is that the immutability is not really enforced in the interface: a client can still *try* to change a frozen contact, something that is impossible in [1]. _Questions:_ Am I right in going the immutable way here ? (I've thought of 2 other solution to the shortcomings of the first design: having the contacts cooperate with the addressbook or using deepcopy when adding and deleting contacts.) If so, which implementation would you chose ? -- There are 10 types of people in the world... those who understand binary and those who don't.