mike at tecc.co.uk
Thu Nov 1 15:23:43 CET 2001
(Apologies, BTW., to everyone who's been added to this ZOOM mailing
list and so has come into this discussion half way through. Hope it's
not too opaque. Some of these issues will be germane to Bradley and
Ian's Java work, but I'd understand if Rob thought it a little
tangential to what he's doing!)
> Date: Thu, 1 Nov 2001 11:44:57 +0000
> From: Ashley Sanders <zzaascs at irwell.mimas.ac.uk>
> > But if you'd like a pointer to a resultSet you can do that with
> > new operator (on the constructor or resultSet). What I'm saying is
> > that if you want them you can have them. If want a local object
> > you can do that too.
> Okay, by changing
> resultSet *rs = c->search(q);
> resultSet *rs = new resultSet(c, q);
> we can have both ways. Fair enough -- if Mike is willing to
> change the spec.
OK, this looks good.
I agree with whoever it was that said we shouldn't even consider the
putative ZOOM::connection::searchStack() method: that was a thought
experiment which has helped me to clarify what the issue is.
So on the TSOBOWTDI principle (There Should Only Be One Way To Do It),
I suggest that we take the bold step of _throwing away_ the search()
method from the ZOOM::connection class, and _replace_ it with a
resultSet constructor whose arguments are a connection and a query.
Then we'll need a little bit of fancy footwork in the binding's
documentation to explain how this captures the "spirit" of the
search() method prescribed by the abstract binding.
Next question. Those connection and query arguments. Should they be
"connection", "connection*" or maybe even (Yeuch!) "connection&"?
(Same issues for queries, I think.) Let's hear the arguments for and
against each of them.
> It also opens up the way for defining operator, so you could say
> resultSet rs (c, q);
> const record *rec = rs;
In Bjarne Stroustrup's _The C++ Programming Language_, third edition
(and in the second edition, for that matter), the quotation that opens
the chapter on Operator Overloading is:
When _I_ use a word it means just what
I choose it to mean - neither more nor less.
- Humpty Dumpty
But back in the days of the first edition (has anyone else ever even
_seen_ that? It was not much thicker than K&R), the same chapter
opened with this, far more apposite, quote:
Here be dragons.
(If more evidence were needed of the degradation on the quality of
this series of books in time, the third edition sets its code
fragments in _italics_ for heaven's sake, instead of the fixed-width
font passed down to us from K&R themselves.)
I would prefer _not_ to wade in the dangerously deep and treacherous
waters of operator overloading. Not only does it violate the
TSOBOWTDI principle, but it will lay our lack of idiomatic familiarity
with C++ bare in a way that nothing we've yet done approaches.
I think it would be a big effort, a lot of danger of fouling up
completely, and all for at best a very very small gain; more likely a
negative net gain as the complexity of our spec shot up.
Anyone want to argue? Come on then, I'll take you all on! :-)
> Which brings us on to who owns the record objects. I would like
> them to be owned by the resultSet unless copied using clone() (or
> some other method.) Mike, are you suggesting that every time I
> get a record with getRecord() that it returns a new object that I
> have to delete when I've finished with it?
Yes, that's what I was suggesting; but I am (as always, except on the
subject of operator overloading :-) open to discussion.
> So, if I want to print the title of each record in a
> result set I have to do:
> for (size_t sz = 0; sz < rs.size (); ++sz)
> record *ps = rs.getRecord (sz);
> cout << ps->field ("title") << endl;
> delete ps;
> whereas, if getRecord() returned a const pointer to a record
> owned by the resultSet, I could just say:
> for (size_t sz = 0; sz < rs.size (); ++sz)
> cout << rs.getRecord (sz)->field ("title") << endl;
> What am I missing this time?
You're not missing anything. This is a valid counter-argument to the
position I was advocating.
Again, I'd like to hear more of what others have to say on this
subject, but I _think_ I still prefer objects to be autonomous. Even
if a given piece of code needs to be more complex to deal with this
arrangement, the system as a whole is simpler because it's easier to
describe, document and understand what the memory-management semantics
are: _every_ object is responsible for itself and only itself.
If we go the way we seem to be going with the resultSet constructor,
then we will presumably do the same with the record constructor, which
will replace the resultSet::getRecord() method. Then your code could
for (size_t sz = 0; sz < rs.size (); ++sz)
cout << record(rs, sz)->field ("title") << endl;
At least, I think it can.
> Mike, I don't think a searchStatic() function should be considered
> at all.
Oh, it was you :-)
/o ) \/ Mike Taylor <mike at miketaylor.org.uk> www.miketaylor.org.uk
)_v__/\ "You cannot really appreciate Dilbert unless you've read it in
the original Klingon." -- Klingon Programming Mantra
More information about the ZOOM