I think this post is quite apt.
At 02:12 AM 5/25/01 -0400, Chip Turner wrote:
>Gunther Birznieks <[EMAIL PROTECTED]> writes:
>
> > While I think that it is clever to allow an interface to change where
> > the parameters come from, I think in practice there are different
> > things to expect. eg how to deal with multi-values? How to deal with
> > file upload field? I think there are quirks in various libraries.
>
>Indeed, these are open questions that aren't dealt with so easily with
>a closure. But I think for a general widget set, a closure would
>work. If you want to get really tricky, you can bless the
>closure... but at that point, you should just be using a class in the
>first place.
>
> > I do not think these things are insurmountable. And Chip's suggestion
> > stands a good chance of working. I do also think there are so few
> > libraries to deal with parameters that it would not be an unreasonable
> > design decision to make the Widget controller hard code knowledge of
> > CGI.pm, Apache::Request and any others since there really aren't many.
>
>I disagree here; Mason, Apache::ASP, embperl, straight modperl,
>CGI.pm, the various CGI accelerators, etc, are a variety of
>interfaces. Anytime you have an application framework (or whatever
>they're called this week), you can have a different interface to even
>the simplest of things like form variables.
>
>Another nice thing about not requiring CGI.pm or libapreq is you can
>actually feed the formvars from something besides an HTTP submission
>(useful for page generation into flat html, or for testing).
>
> > Likewise, we might consider that CGI.pm is the primary source of
> > information, but if I pass a db record set to the widget controller
> > along with CGI.pm, I may want CGI.pm to override the database but if
> > there is no CGI.pm value, then the value from the database field will
> > be placed in the widget instead.
> >
> > Anyway, I am sorry if this sounds quite odd. I am not good at
> > explaining things when I am tired, but I did at least want to throw
> > out the idea of not being married yet to a particular way of having a
> > widget consume data from a data source.
>
>I agree that there are a lot of various issues here for when it comes
>to handling data input and output. But I think that for something
>like a Widget set to be useful, it needs to be as decoupled as
>possible from all external libraries, and still be able to play with
>them. Now, that means one of two things.
>
>(a) Some kind of base class (Some people suggest using an "implied"
>interface without a true abstract base class that defines the various
>methods; I am very much against this because it can lead to somewhat
>sloppy programming. If you're going to use objects, use them in a way
>that other languages tend to use them and not as typeless chunks that
>respond to various kinds of black magic poking and prodding). I
>personally only see this being not-the-best-option because of
>unnecessary complexity for the fairly simple task at hand. If the
>task were more complicated, there is no doubt this is the proper
>route.
>
>(b) The other option, a closure, makes the simple things simple, but
>the harder things a bit harder. File uploads, for instance, and
>cookies. Of course, since a Widget set rarely (if ever) would need to
>display the content of an upload as part of a re-rendering of the
>widget, I don't see this being a common use. Likewise, cookies don't
>seem as needed to be for more or less the same reason (if you're using
>raw cookies to pass complex data around, you're probably doing more
>work than you need to; things like Apache::Session make life easier
>without forcing you to muck with cookies at every data access point).
>
>It gets ugly though if you -do- want cookies. Does your abstract base
>class (ABT) have to be typed for every possible pair of form var
>input and cookie input methods? Is there a separate interface for
>each, thus complicating the API slightly?
>
>The more I think about it, the more wrong it seems for the Widget
>library to assume anything about where its data is coming from. It
>should either be from a closure or a class based on an ABT. A third
>option is that all widgets are actually generated by a generator
>instance of a class; this could simplify the API so that you needn't
>pass the CGI object or closure around all the time. In this case, you
>could derive from this base class to create new ways of gathering data
>from CGI and cookies.
>
>This is more or less a standard design pattern -- data interfacing.
>There are a number of solutions. I just hope whatever gets written is
>present and future proof enough to not depend on any particular
>interface (such as CGI or libapreq), or at the very least made to
>easily use others. You never know when someone else may have another
>templating technology that has a different interface!
I think your post makes a lot of sense. How about this as a simple proposal.
Widgets should be able to get data from a data source. The interface to
obtaining data consists of a name/value pair where a value that is returned
is a scalar if one value, a ref to an array if multi valued.
Widgets should be able to set data to a data source. The same interface
applies (setting data based on name/value pair).
I think this is fairly future proof for what widgets need to know.
The following Widget-specific data sources would be interesting to me:
1) CGI.pm get/post param
2) CGi.pm cookie name/value
3) Apache::Request
4) DBI result set row
5) Apache::Session
As a first cut of possible default supported interfaces. In our
contribution, we would support an interface to Extropia::Session (which
wraps around Apache::Session but has a few more classes to it) and
Extropia::DataSource (which is our abstraction on top of DBI and other data
sources in our toolkit). Otherwise, we need 1 and 2 for the Extropia toolkit.
So I only need 4 data sources initially.
I recommend that this be a Widget::DataSource
Later,
Gunther