From: Ray Z. <rz...@co...> - 2004-12-03 19:43:17
|
Chris, I only got a chance to skim over your e-mails the other day. Now that I've looked at your example more carefully, I don't think you got exactly what I'm proposing yet, so I'll try to clarify and then respond to some of your points. On Dec 1, 2004, at 2:27 PM, Chris Winters wrote: > book: > book_id, title, publisher_id > > publisher: > publisher_id, name > > book_author: > book_id, author_id > > author: > author_id, name > > Book 1 ---> 1 Publisher > Book 1 ---> * Author > > my $book = Book->fetch(42); > $book->publisher == object (whether manual/lazy fetch) > $book->publisher_id == ID > $book->author == list of objects (whether manual/lazy fetch) > > Is that right? Because it sounds from the discussion as if: > > $book->publisher == sometimes ID, sometimes object, > depending on the configuration > > which IMO is very confusing. In this example it appears that book has a 'publisher_id' field only, so there would be no 'publisher' method. For the sake of describing my proposal let me rename the 'publisher_id' field to 'publisher', which will still hold the publisher's id in the database. My proposal is as follows: First, regardless of the configuration ... 1. The publisher column in the database holds the ID of a publisher object. 2. The book object has a fetch_publisher() method for fetching the object (config can optionally specify different method name). $book->fetch_publisher == object 3. The book object has a publisher() method which always returns the value of the field in the book object. i.e. $book->publisher == $book->{publisher} For manual fetch configuration, the publisher field in the book object is ALWAYS the ID stored in publisher column in the database. $book->publisher == ID For auto/lazy fetch configuration, the publisher field in the book object is ALWAYS the publisher OBJECT whose ID is stored in the publisher column in the database. $book->publisher == object In the case of auto-fetch, the assignment, $book->{publisher} = $book->fetch_publisher, is executed when the $book object is fetched. In the lazy-fetch case it happens the first time $book->publisher is called (or $book->{publisher} is accessed). Again, the purpose of this is to allow me to think of my book's publisher field as a Publisher object. On Dec 1, 2004, at 5:24 PM, Chris Winters wrote: > I believe I read through everything. I just think you're overestimating > how much time and effort people are willing to spend to sort these > out. We > who have been using SPOPS for a while see the relationship between the > configuration and the code as blindingly obvious. > > But for new people -- or even people who only use SPOPS occasionally -- > it's not. And the idea that the behavior of an existing method could > change based on configuration is very disconcerting. People like to > think > of their objects as somewhat stable -- even Perl people! -- and when we > change the meaning under the hood like that it's untrustworthy. > > OTOH, the idea that something *new* happens -- like adding new methods > -- > as a result of configuration changes isn't so bad because you have the > choice if you want to use the new feature or not. I agree completely. But we are not changing the behavior of any existing methods. The publisher method has always returned the value held in the publisher field of the Perl object and that is what it still returns. What we are doing is adding the *new* ability to configure a field to be an auto/lazy-fetched object instead of simply the ID. This is a new feature which is why I agree that it is a good idea to use a name other than 'has_a' for this config. I really don't like the idea of a 'publisher_id' field configured to auto-fetch an object into a 'publisher' field. I think using two fields clutters up the object unnecessarily and creates other ambiguities that have to be resolved/documented. Since this wasn't envisioned when I wrote up the detailed description of my original design, I haven't thought through this in detail, but here are two issues off the top of my head: - What do you call the field where you stash the auto-fetched object? Always specify explicit name in config? - When auto-saving how should SPOPS handle inconsistencies between the id of the object in the publisher field and the value in the publisher_id field? Or to put it another way, if I want to re-assign a book's publisher, do I assign a new id to the publisher_id field or do I assign a new object to the publisher field? Seems much more messy to me for something that I consider to be completely new functionality (no backward compatibility issues to worry about). While it does eliminate the need for the manual fetch option, as Simon mentioned earlier (and probably even lazy fetch), it also eliminates one of the main features for me, which is the ability to take an existing field and treat it conceptually as an object. I suppose if someone insisted on being able to auto-fetch into a second field I wouldn't object too strongly to permitting that as an option, but I think it adds unnecessary complexity which would need to be documented. Ray Zimmerman Director, Laboratory for Experimental Economics and Decision Research 428-B Phillips Hall, Cornell University, Ithaca, NY 14853 phone: (607) 255-9645 |