perl-widget-developer Mailing List for Perl Widget Library (Page 7)
Status: Alpha
Brought to you by:
spadkins
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(8) |
Jun
(132) |
Jul
(3) |
Aug
(6) |
Sep
|
Oct
(6) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2005 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(9) |
2007 |
Jan
(2) |
Feb
(2) |
Mar
(1) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(19) |
Sep
(6) |
Oct
(5) |
Nov
(5) |
Dec
(3) |
2008 |
Jan
|
Feb
(7) |
Mar
(34) |
Apr
(13) |
May
(15) |
Jun
(5) |
Jul
(14) |
Aug
(6) |
Sep
(6) |
Oct
(3) |
Nov
(1) |
Dec
|
From: Stephen A. <ste...@of...> - 2001-06-12 03:01:08
|
At 05:08 PM 6/11/2001 -0500, you wrote: >"Jay Lawrence" <Ja...@La...> wrote: >>James and Stephen, >> >>Could you please expand on what you mean by static methods? > >These would be methods that are not tied to an instance -- the `new' method >(basically, any constructor) is an example of a usually static method. Any >method that requires an instance of an object class is not a static method. > >Perl blurs the line between static and non-static methods. C++ is very >explicit and requires the `static' keyword before the function declaration. > >The static methods do not have an object to get any information from, so any >configuration information they get would have to either come from the function >arguments or from globals. >-- >James Smith <JG...@TA...>, 979-862-3725 >Texas A&M CIS Operating Systems Group, Unix > James is correct on all points. For example $wc = Widget->controller(); is a "static" method on the Widget package. No instance of a "Widget" class was required in order to call the controller() method. Any routine called from the package name (i.e. Package::Name->method_name()) is a static method. (The terminology indeed comes from C++ and Java.) A "normal" method call (dynamic?) is called on an instance of a class. i.e. $query = CGI->new(); # this is a static method call, called from package print $query->param("x"); # this is a normal (dynamic) method call, called from object The "Factory" pattern is a standard way of constructing objects without knowing what type of objects they actually are. In order to instantiate an object, you normally need to know the class of the object. With a factory, you can let the factory decide. In this way, $wc = Widget->controller(); is letting the static method, "controller()", in the Widget package decide which class it should instantiate when returning a Controller. Similarly, with $date_widget = $wc->widget("date"); we are letting the controller decide (based on config and runtime information) what actual class to instantiate. Thus, both the Widget package and Widget::Controller objects are acting as factories in the PWL. Stephen |
From: Stephen A. <ste...@of...> - 2001-06-12 02:49:48
|
At 05:52 PM 6/11/2001 -0400, you wrote: >I've gotta claim ignorance on what you guys are talking about when you're >refering to factories and controllers. > >Personally - I expected that I'd instanciate what ever widgets I the app >developer wanted, fill their properties at instanciation or afterwards, and >then call their methods when I needed something from them. > >I guess the purpose of having a controller or factory is to aid in this >process? Possibly provide other services? Maybe I am thinking that >controller code is slightly beyond scope of widgets. > >Perhaps more detail on what you guys see happening here would be of value >not just to me but us all. > >Jay > Jay, This is a good question... even a Frequently Asked Question. Thus, I have answered it in the FAQ that I am writing. http://www.officevision.com/pub/Widget/FAQ.html Please look it over. Stephen |
From: James G S. <JG...@TA...> - 2001-06-11 22:09:48
|
"Jay Lawrence" <Ja...@La...> wrote: >I've gotta claim ignorance on what you guys are talking about when you're >refering to factories and controllers. Controller is just a specific name for a factory in this case, except the controller has certain configuration information the widgets can reference. For example, the controller knows what rendering environment to use or which state object to use by default. At least in my email, I use the two terms controller and factory interchangably. >Personally - I expected that I'd instanciate what ever widgets I the app >developer wanted, fill their properties at instanciation or afterwards, and >then call their methods when I needed something from them. The controller/factory does some of this for you when you use it to create widgets. >I guess the purpose of having a controller or factory is to aid in this >process? Possibly provide other services? Maybe I am thinking that >controller code is slightly beyond scope of widgets. -nod- The controller/factory handles configuration issues that are pan-widget, basically. The dictionary, state object, and rendering environment are controlled by the controller/factory in my code. The factory also knows where to find the widget classes (Widget::* or some other configurable base module name). -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: James G S. <JG...@TA...> - 2001-06-11 22:05:42
|
"Jay Lawrence" <Ja...@La...> wrote: >James and Stephen, > >Could you please expand on what you mean by static methods? These would be methods that are not tied to an instance -- the `new' method (basically, any constructor) is an example of a usually static method. Any method that requires an instance of an object class is not a static method. Perl blurs the line between static and non-static methods. C++ is very explicit and requires the `static' keyword before the function declaration. The static methods do not have an object to get any information from, so any configuration information they get would have to either come from the function arguments or from globals. -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: Stephen A. <ste...@of...> - 2001-06-11 21:57:13
|
At 04:32 PM 6/11/2001 -0500, James G Smith wrote: >Stephen Adkins <ste...@of...> wrote: >>At 01:43 PM 6/11/2001 -0500, you wrote: >I've seen both static and non-static approaches to this in the email. Static >methods will come back to bite us, imho, because of either the lack in >configurability or the presence of global information. ... >Well, I've seen us be inconsistant as a group, so I wanted to make sure >everyone was on the same page. OK. Thanks for helping us get straight. No globals! >James Smith <JG...@TA...>, 979-862-3725 >Texas A&M CIS Operating Systems Group, Unix Stephen |
From: Jay L. <Ja...@La...> - 2001-06-11 21:55:00
|
James and Stephen, Could you please expand on what you mean by static methods? Jay From: "James G Smith" <JG...@TA...> > Hmm... Not sure what the static methods get us then if we can't configure > them any. Any configuration of the static methods would involve globals. > > I've seen both static and non-static approaches to this in the email. Static > methods will come back to bite us, imho, because of either the lack in > configurability or the presence of global information. > > >James, you're giving good input and obviously putting some good thought into > >the topic. > >I just don't know what you're talking about in this email. > > Well, I've seen us be inconsistant as a group, so I wanted to make sure > everyone was on the same page. > -- > James Smith <JG...@TA...>, 979-862-3725 > Texas A&M CIS Operating Systems Group, Unix > > > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: Jay L. <Ja...@La...> - 2001-06-11 21:50:51
|
I've gotta claim ignorance on what you guys are talking about when you're refering to factories and controllers. Personally - I expected that I'd instanciate what ever widgets I the app developer wanted, fill their properties at instanciation or afterwards, and then call their methods when I needed something from them. I guess the purpose of having a controller or factory is to aid in this process? Possibly provide other services? Maybe I am thinking that controller code is slightly beyond scope of widgets. Perhaps more detail on what you guys see happening here would be of value not just to me but us all. Jay From: "James G Smith" <JG...@TA...> > Stephen Adkins <ste...@of...> wrote: > >At 01:43 PM 6/11/2001 -0500, you wrote: > >>Many of the examples have Widget -> method() for making a widget. I don't > >>think this is as good an idea as creating an instance of a factory class and > >>using that to create widgets. > > > >Can you clarify what examples you are talking about? > > Jay has some that I am aware of: > > > $widget=Widget->new( thaw => $stored_data ); > > for example. I think others have used a similar approach at times. I'm > seeing more of the $wc->widget than Widget->new :/ I didn't do an exhaustive > search for examples, so I might have missed some, esp. from earlier. > > >There are no globals in the code. > >Perhaps you mean static methods in the Widget package? > >(This doesn't suffer from any threading problems I am aware of.) > > Hmm... Not sure what the static methods get us then if we can't configure > them any. Any configuration of the static methods would involve globals. > > I've seen both static and non-static approaches to this in the email. Static > methods will come back to bite us, imho, because of either the lack in > configurability or the presence of global information. > > >James, you're giving good input and obviously putting some good thought into > >the topic. > >I just don't know what you're talking about in this email. > > Well, I've seen us be inconsistant as a group, so I wanted to make sure > everyone was on the same page. > -- > James Smith <JG...@TA...>, 979-862-3725 > Texas A&M CIS Operating Systems Group, Unix > > > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: James G S. <JG...@TA...> - 2001-06-11 21:30:06
|
Stephen Adkins <ste...@of...> wrote: >At 01:43 PM 6/11/2001 -0500, you wrote: >>Many of the examples have Widget -> method() for making a widget. I don't >>think this is as good an idea as creating an instance of a factory class and >>using that to create widgets. > >Can you clarify what examples you are talking about? Jay has some that I am aware of: > $widget=Widget->new( thaw => $stored_data ); for example. I think others have used a similar approach at times. I'm seeing more of the $wc->widget than Widget->new :/ I didn't do an exhaustive search for examples, so I might have missed some, esp. from earlier. >There are no globals in the code. >Perhaps you mean static methods in the Widget package? >(This doesn't suffer from any threading problems I am aware of.) Hmm... Not sure what the static methods get us then if we can't configure them any. Any configuration of the static methods would involve globals. I've seen both static and non-static approaches to this in the email. Static methods will come back to bite us, imho, because of either the lack in configurability or the presence of global information. >James, you're giving good input and obviously putting some good thought into >the topic. >I just don't know what you're talking about in this email. Well, I've seen us be inconsistant as a group, so I wanted to make sure everyone was on the same page. -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: Stephen A. <ste...@of...> - 2001-06-11 21:26:31
|
At 10:55 AM 6/11/2001 -0700, ja...@la... wrote: > >I move that my suggestion be placed on a list of features for further review at a later time. > >Further more I would move that we create a list of tabled feature suggestions that will be subsequently reviewed in light of all design requirements and feature requests. > >Jay > P.S. Anyone who suggests a feature that you want to make sure I include on the TODO list, please make a comment to that effect in the email. |
From: Stephen A. <ste...@of...> - 2001-06-11 21:25:28
|
Hi, At 10:55 AM 6/11/2001 -0700, you wrote: > >I move that my suggestion be placed on a list of features for further review at a later time. > >Further more I would move that we create a list of tabled feature suggestions that will be subsequently reviewed in light of all design requirements and feature requests. Good idea. We have a TODO file, which I am maintaining. I added the freeze/thaw and the accessor features. You can track the TODO file in CVS. http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/perl-widget/Widget/TODO >Jay Stephen |
From: Stephen A. <ste...@of...> - 2001-06-11 21:15:05
|
At 01:43 PM 6/11/2001 -0500, you wrote: >Many of the examples have Widget -> method() for making a widget. I don't >think this is as good an idea as creating an instance of a factory class and >using that to create widgets. Can you clarify what examples you are talking about? >In a threaded environment, we don't want to rely on globals for configuration >if the configuration might be different in different threads. This only might >come into play in a threaded Perl or in mod_perl 2.0. Not sure exactly how it >plays out, but better to be thread-safe just in case. There are no globals in the code. Perhaps you mean static methods in the Widget package? (This doesn't suffer from any threading problems I am aware of.) >We might want two different configurations in one script. Not sure exactly >why, but better to allow it while not understanding why than to disallow >because we can't see a reason for allowing. There's no *good* reason (that I >can think of) for not allowing it. > >Instead of: > > $widget = Widget -> new("Widget::Type"); I don't know what you're getting at. All of the examples and the code use the controller as the factory. $widget = $wc->widget($wname); >have > > $controller = new Widget::Controller; > $controller -> state(new Widget::State); > # etc... > $widget = $controller -> widget("Type"); > > >These are the reasons I went with an instance of Widget::Controller being the >factory in my development code instead of Widget -> method. Just thought I'd >throw it out there for possible discussion. :) James, you're giving good input and obviously putting some good thought into the topic. I just don't know what you're talking about in this email. >James Smith <JG...@TA...>, 979-862-3725 >Texas A&M CIS Operating Systems Group, Unix Stephen |
From: James G S. <JG...@TA...> - 2001-06-11 18:41:23
|
Many of the examples have Widget -> method() for making a widget. I don't think this is as good an idea as creating an instance of a factory class and using that to create widgets. In a threaded environment, we don't want to rely on globals for configuration if the configuration might be different in different threads. This only might come into play in a threaded Perl or in mod_perl 2.0. Not sure exactly how it plays out, but better to be thread-safe just in case. We might want two different configurations in one script. Not sure exactly why, but better to allow it while not understanding why than to disallow because we can't see a reason for allowing. There's no *good* reason (that I can think of) for not allowing it. Instead of: $widget = Widget -> new("Widget::Type"); have $controller = new Widget::Controller; $controller -> state(new Widget::State); # etc... $widget = $controller -> widget("Type"); These are the reasons I went with an instance of Widget::Controller being the factory in my development code instead of Widget -> method. Just thought I'd throw it out there for possible discussion. :) -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: James G S. <JG...@TA...> - 2001-06-11 18:30:10
|
ja...@la... wrote: >Bingo! > >I suggest that a widget contain a list of properties to be saved when frozen and to be recalled when thawing. > >@freeze_props=qw(fname size width colour shape foo bar); > >Other properties will no doubt exist for any given widget but only the above actually get frozen or thawed. -nod- makes sense to me. I'll sit on it a bit and think -- I want the freeze/thaw process to have the following properties: trivial for the widget developer - a widget should only have to worry about itself, not it's parent classes. trivial for the widget user - only use $widget -> freeze and Widget -> thaw($data). I think the @freeze_props idea is the right way to do this, but want to make sure I see how it all fits together before committing to it. -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: <ja...@la...> - 2001-06-11 18:10:26
|
Bingo! I suggest that a widget contain a list of properties to be saved when frozen and to be recalled when thawing. @freeze_props=qw(fname size width colour shape foo bar); Other properties will no doubt exist for any given widget but only the above actually get frozen or thawed. Cheers, J On Mon, 11 June 2001, James G Smith wrote: > > "Jay Lawrence" <Ja...@La...> wrote: > >From: "Gunther Birznieks" <gu...@ex...> > >> How do you propose supporting this API-wise? > > > >$stored_data = $widget->freeze; > > Sounds good to me. > > >This should return a data structure (i.e. hash) in a format like Storable or > >Data::Dumper of all of the properties of the object that are persistant. I > >don't belive that you can just freeze or thaw your runtime object as it > >might have extra information that is not suitable for storing. (ie/ object > >ref to controller object, etc). Not to mention it is implementation > >specific - and if you change your implementation your frozen objects won't > >be as easy to recall. > > The frozen widget should only contain data specific to the widget and not any > state information, since that may change before it is thawed out. Makes sense > to have the function be in the widget. I'll put a freeze method in my > Widget::Base before putting it up so people can see how it might work (at > least my way of doing it :/). > > >My idea to get this data back might be as follows: > > > >$widget=Widget->new( thaw => $stored_data ); > > # Will know what class this object is from contents of $stored_data > >or > >$widget=new Widget::Foo; > >$widget->thaw( $stored_data ); > > # Gotta check that stored_data widget class matches this widget class, > >eh? > > Perhaps also: > > $widget = Widget -> thaw($stored_data); ? > > I'll try to stick that into my Widget::Controller package as well. > -- > James Smith <JG...@TA...>, 979-862-3725 > Texas A&M CIS Operating Systems Group, Unix > > > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer |
From: <ja...@la...> - 2001-06-11 17:55:12
|
I move that my suggestion be placed on a list of features for further review at a later time. Further more I would move that we create a list of tabled feature suggestions that will be subsequently reviewed in light of all design requirements and feature requests. Jay |
From: James G S. <JG...@TA...> - 2001-06-11 17:25:50
|
"Jay Lawrence" <Ja...@La...> wrote: >From: "Gunther Birznieks" <gu...@ex...> >> How do you propose supporting this API-wise? > >$stored_data = $widget->freeze; Sounds good to me. >This should return a data structure (i.e. hash) in a format like Storable or >Data::Dumper of all of the properties of the object that are persistant. I >don't belive that you can just freeze or thaw your runtime object as it >might have extra information that is not suitable for storing. (ie/ object >ref to controller object, etc). Not to mention it is implementation >specific - and if you change your implementation your frozen objects won't >be as easy to recall. The frozen widget should only contain data specific to the widget and not any state information, since that may change before it is thawed out. Makes sense to have the function be in the widget. I'll put a freeze method in my Widget::Base before putting it up so people can see how it might work (at least my way of doing it :/). >My idea to get this data back might be as follows: > >$widget=Widget->new( thaw => $stored_data ); > # Will know what class this object is from contents of $stored_data >or >$widget=new Widget::Foo; >$widget->thaw( $stored_data ); > # Gotta check that stored_data widget class matches this widget class, >eh? Perhaps also: $widget = Widget -> thaw($stored_data); ? I'll try to stick that into my Widget::Controller package as well. -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: James G S. <JG...@TA...> - 2001-06-11 17:20:12
|
Stephen Adkins <ste...@of...> wrote: >At 10:52 AM 6/11/2001 -0400, you wrote: >>I truly believe that we will end up going back and making all code use >>accessor functions. > >All code *outside* the class should *always* use accessor functions. >The only question to be resolved is whether code *inside* the class >(i.e. in other methods of the class) must obey this rule also. >In other words, we treat each attribute as though it is "private". Whether to use the direct hash value or the accessor function depends on a few things: (1) Is this the accessor function? Don't want too deep a recursion. (2) Do we want to value in the hash or the value of the attribute as seen by external objects? The default accessor might have some nice things like checking the state object or bounds checking that we may not want to maintain in multiple places. >I think that we leave the choice to whomever codes the class. Agreed. The internals of the class are not important as long as it behaves in the proper fashion (thinking as an end user here) -- that's what OOP is all about (kindof). -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: Stephen A. <ste...@of...> - 2001-06-11 15:37:49
|
At 10:52 AM 6/11/2001 -0400, you wrote: >I truly believe that we will end up going back and making all code use >accessor functions. All code *outside* the class should *always* use accessor functions. The only question to be resolved is whether code *inside* the class (i.e. in other methods of the class) must obey this rule also. In other words, we treat each attribute as though it is "private". I think that we leave the choice to whomever codes the class. >I don't think this is a matter for the end developer but rather those who >are trying to offer widget functionalities. If we want to have *flexibility* >in how widgets function based on need - from very simple operation to very >complex - we must take the necessary steps to allow for this. > >The example I raise is the one of multilingual text property. So, for >example a label property for your widget. Now, most of you want one language >and would make sense to store as a string: > $widget->{'label'}="First name"; > sub label { > my $self=shift; > return $self->{'label'}; > } > >Me? I've got something else in mind... > $widget->{'label'}{'en'}="First name"; > $widget->{'label'}{'fr'}="prenom"; > sub label { > my $self=shift; > my $lang=$self->container->user_lang; > if (exists $self->{'label'}{$lang}) { > return $self->{'label'}{$lang}; > } > return $self->{'label'}{$self->container->default_lang; } > } Exactly. >So, any time in another method where you've got something like: >sub html { > my $self=shift; > > return "Your label is ".$self->{'label'}; >} > >It will work for the first simple case but not for the more complex case. > >sub html { > my $self=shift; > return "Your label is ".$self->label; >} > >This works for both cases. > >Doesn't this make sense? I know you're trading preformance for flexibility >but isn't that a stated design objective? Flexibility will take precedence >over performance. I agree with this. Flexibility and Performance are both design objectives, and Flexibility takes precedence over Performance (at least for now). >Jay Stephen |
From: James G S. <JG...@TA...> - 2001-06-11 14:54:11
|
The Internet is being a bit flaky right now with all the water in Houston. TAMU is routing through Austin for now, so we can get email there. My ISP at home is a different matter -- two of the connections that still need to be checked by the phone co. are underwater at the moment in Houston. Over the weekend I threw together a Widget library (there had been some mention that we should do an implementation based on some of our ideas and see what happens...) to see how some things might work out. As soon as I get my machine at home on the network I'll make it available for people to look at. I use render() here, but it really doesn't enter the picture since "" is overloaded. The basic classes (actual documentation is written for most of them): Widget::Controller -- makes widgets and manages which environment is being used Widget::Base -- base class for widgets - handles rendering/displaying and other basic functions Widget::Array -- an array of widgets - rendering the array renders all the component widgets Widget::Form -- derived from Widget::Array - provides a wrapper for forms Widget::Selector -- basic single- or multi- selection Widget::Selector::Month -- offers a single- or multi- selection for months with validation Widget::Date -- derived from Widget::Array - provides a set of selections for selecting a date Widget::Text -- static text widget with hooks for translation Widget::State -- a widget (derived from Widget::Base) for handling state - rendering this widget saves state in an appropriate manner Widget::Dictionary -- base abstract class for defining a translation mechanism Still need to write: Widget::Selector::{Day,Year}. Basic features: Rendering is either done with a <class>->render_<env> method (Widget::Selector -> render_html, for example) or with <class>::<env>->render method (Widget::Selector::HTML -> render, for example). <class>::<env> is a lot easier to do than trying to put <env> in the middle of the class name. AUTOLOAD is used to handle widget attributes. This allows for default values to come from the state object, if one is present, without additional code in the actual widget (handled in Widget::Base). Only attributes requiring special handling and/or validation need explicit code. String escaping is handled similar to rendering. The widget need not know which environment it is in in order to escape a string correctly. This allows for greater reuse of rendering code if two environments are very similar. The state object handles saving state. If it's by putting a lot of hidden fields in a form, then so be it. It might also be through a session with only a session id being put in a form somewhere. It's up to the state object to figure all that out -- it's the state of the script. This takes away the burden of saving values from the widgets. An example: my $controller = new Widget::Controller; $form = $controller -> widget("Form"); # get the reference to the tied array $array = $form -> ARRAY; @{$array} = ( "Some text without translation.<br>", $controller -> widget("Text", ( value => "Text with translation." ) ), "<br>", $controller -> widget("Selector", ( name => "entree", value => "a", values => ( a => "apple", b => "banana", c => "calamari" ), ) ) ); print $form; __END__ Results: <form action="/scriptname" method="POST"> Some text without translation<br> Text with translation <br> <select name="entree"> <option value="a" SELECTED>apple</option> <option value="b">banana</option> <option value="c">clamari</option> </select> </form> -- James Smith <JG...@TA...>, 979-862-3725 Texas A&M CIS Operating Systems Group, Unix |
From: Jay L. <Ja...@La...> - 2001-06-11 14:51:40
|
I truly believe that we will end up going back and making all code use accessor functions. I don't think this is a matter for the end developer but rather those who are trying to offer widget functionalities. If we want to have *flexibility* in how widgets function based on need - from very simple operation to very complex - we must take the necessary steps to allow for this. The example I raise is the one of multilingual text property. So, for example a label property for your widget. Now, most of you want one language and would make sense to store as a string: $widget->{'label'}="First name"; sub label { my $self=shift; return $self->{'label'}; } Me? I've got something else in mind... $widget->{'label'}{'en'}="First name"; $widget->{'label'}{'fr'}="prenom"; sub label { my $self=shift; my $lang=$self->container->user_lang; if (exists $self->{'label'}{$lang}) { return $self->{'label'}{$lang}; } return $self->{'label'}{$self->container->default_lang; } } So, any time in another method where you've got something like: sub html { my $self=shift; return "Your label is ".$self->{'label'}; } It will work for the first simple case but not for the more complex case. sub html { my $self=shift; return "Your label is ".$self->label; } This works for both cases. Doesn't this make sense? I know you're trading preformance for flexibility but isn't that a stated design objective? Flexibility will take precedence over performance. Jay ----- Original Message ----- From: "Gunther Birznieks" <gu...@ex...> To: <per...@li...> Sent: Sunday, June 10, 2001 9:46 PM Subject: Re: [Perl-widget-developer] Properties - object variables vs. accessors > I think that I prefer the 2nd strategy first. It is possible that it is > necessary to go back and recode to support inheritence. However, there is > something that has been overlooked here. > > Inheritence is probably not the way most people will deal with widgets. I > would posit based on my prior experience is most cases of widget reuse > involves a has-a rather than is-a relationship -- a containment issue. > > So if I write a DateTime widget, it would have a date widget and a time > widget but usually not inheriting from Date widget and then adding Time > functionality. > > Of course, there are cases where inheritence is useful. I am not saying > they don't exist. But in my experience with writing widgets for JSPs, I > have almost never had to resort to inheritance. > > At 12:25 PM 6/5/2001 -0700, ja...@la... wrote: > >Great - and you are absolutely right about the two camps for > >implementation. In my work I took the 2nd strategy initially and ended up > >going back and redoing that code to use accessor methods anyway. > > > >By using accessors at all times you are going to allow people like me to > >override data type declarations with what I want but support Gunther's > >wish for total simplicity of implementation. > > > >I do accept that there is a performance tradeoff.* Perhaps, before getting > >too excited about performan implications we might choose to benchmark > >this. How you implement it will affect the performance. (ie/ using > >AUTOLOAD could be done slow - but creating closures can make it fast.) > >Also - by itemizing the list of possible keys upfront can you not open to > >the possiblity of a pseudohash which is faster and more compact that > >standard hashes? > > > >Jay > > > >* I remember Stephen's statement of flexibility over performance! > > > >On Tue, 05 June 2001, Stephen Adkins wrote: > > > > > > > > Hi, > > > > > > Yes, we absolutely need accessors. > > > I recommend an AUTOLOAD method implemented on Widget::Base to > > > create accessors automatically (for now, anyway). > > > > > > However, there are two schools of thought on use of accessors vs. > > > accessing the attributes directly. > > > > > > 1. use accessors everywhere, even inside the class > > > 2. use accessors outside the class, access the attribute directly > > > from within the class > > > > > > I prefer #2 for performance. > > > Some people argue #1 so that subclasses are resilient to change in the > > > superclass. I think we just don't have a complex enough code base to > > > make #1 critical. It won't be look before we finalize how to access > > > attributes internally. Then it should be stable. > > > > > > Stephen > > > > > > At 10:22 AM 6/5/2001 -0400, Jay Lawrence wrote: > > > >Hey all, > > > > > > > >I was looking at the code and noticed one thing that will severely > > limit our > > > >implementation flexibility. It has to do with how properties are > > accessed in > > > >a non-abstracted fashion. > > > > > > > >When an widget is created (Widget::Base::new) you pass your properties > > which > > > >then get stuffed in the object hash for later use. > > > > > > > >OK - so you're storing properties like $widget->{'name'} = "button1". (Oh, > > > >BTW, shouldn't you enclose hash keys in quotes? I know it generally works > > > >but it generates warnings). > > > > > > > >And you're obtaining it same way ie: > > > > print "My name is ".$self->{'name'}; > > > > > > > >However, if you choose to have a different storage mechanism OR want > > to get > > > >fancy with how properties are resolved you need to use accessor > > methods. ie/ > > > > print "My name is ".$self->name; > > > > > > > >This way you hide the implementation of the widget (abstraction) from the > > > >calling routine. You actually need to use this strategy everywhere. > > > > > > > >There are a number of ways to handle this: > > > > AUTOLOAD - resolve name of method to a property or raise error > > > > manual accessor contruction - lots 'n lots of subs > > > > automated accessor construction - 1/2 doz packages in CPAN that do the > > > >job > > > > > > > >I know there will be arguments of efficiency vs. flexibility but I do > > recall > > > >Stephen saying that at this stage we'll be thinking more on > > flexibility than > > > >efficiency. But down the road we might be able to trade the expense of a > > > >function call with a more efficient storage mechanism like pseudohashs. > > > > > > > >Jay > > > > > > > > > > > > > > > >_______________________________________________ > > > >Perl-widget-developer mailing list > > > >Per...@li... > > > >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > > > > > > > > > > > >_______________________________________________ > >Perl-widget-developer mailing list > >Per...@li... > >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > > __________________________________________________ > Gunther Birznieks (gun...@eX...) > eXtropia - The Open Web Technology Company > http://www.eXtropia.com/ > > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: Jay L. <Ja...@La...> - 2001-06-11 14:34:20
|
From: "Gunther Birznieks" <gu...@ex...> > How do you propose supporting this API-wise? $stored_data = $widget->freeze; This should return a data structure (i.e. hash) in a format like Storable or Data::Dumper of all of the properties of the object that are persistant. I don't belive that you can just freeze or thaw your runtime object as it might have extra information that is not suitable for storing. (ie/ object ref to controller object, etc). Not to mention it is implementation specific - and if you change your implementation your frozen objects won't be as easy to recall. My idea to get this data back might be as follows: $widget=Widget->new( thaw => $stored_data ); # Will know what class this object is from contents of $stored_data or $widget=new Widget::Foo; $widget->thaw( $stored_data ); # Gotta check that stored_data widget class matches this widget class, eh? Just what I had in mind... > Of course, this post was one of the better ones as some didn't bother > changing subjects at all. :) Thanks for noticing. J > > At 11:06 AM 6/6/2001 -0400, Jay Lawrence wrote: > >The purpose? Ah, good question. More variety of configuration options. I > >expect that I'll want to configure my widgets separate from my code. (At > >least the types of widgets I'm thinking about) > > > >So this gives me the option to configure them elsewhere, save them (freeze), > >and have my code thaw all the widgets that it cares about. FURTHERMORE, if I > >want to give others the chance to configure some or all widgets - I can > >allow them to modify the saved definition and resave it as I deem > >appropriate. > > > >The widget has to know how to freeze and thaw itsself because of course that > >is implementation dependant to some degree. IE/ Data::Dumper would dump out > >the hash that holds all of the widget properties - which in itsself is an > >implementation detail. > > > >Jay > > > > > At 10:05 AM 6/6/2001 -0400, Jay Lawrence wrote: > > > >One other thing I really wanna see is thaw/freeze support. Scary? Not > > > >really. Obviously if you don't wanna thaw and freeze widgets ever this > >will > > > >be no skin off your nose - it is optional to use. > > > > > > > >I belive that one thing needs to happen in the thaw phase - that is a > >"use" > > > >for the widget's class. There is no guarantee that you've "use"d that > >widget > > > >class already. > > > > > > > > > > Interesting idea. > > > What is the purpose of freezing and thawing widgets? > > > > > > Stephen > > > > > > > > > > > > > > >_______________________________________________ > >Perl-widget-developer mailing list > >Per...@li... > >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > > __________________________________________________ > Gunther Birznieks (gun...@eX...) > eXtropia - The Open Web Technology Company > http://www.eXtropia.com/ > > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: Jay L. <Ja...@La...> - 2001-06-11 14:24:20
|
See bottom of message: > At 11:09 AM 6/6/2001 -0400, Stephen Adkins wrote: > >At 09:53 AM 6/6/2001 -0400, Jay Lawrence wrote: > > > > > >Widgets in Template Toolkit - QED > > > > > >Here is something that I prototyped on my own system... > > > - Just to show exactly how simple I'd like the widgets to appear to the > > >template user ... > > > > > >General ideas: > > > - Create hash of widgets: name => Widget::Object > > > - Register this with Template::Toolkit somehow > > > - two places come to mind - in the vars (as I have shown here) > > > - At Template instantiation > > > my $tt=Template->new ( { WIDGETS=>$widgetHashRef } ); > > > - Reference widgets solely by name > > > - I do find the "wc." - "wc.widget" - a bit redundant but understand > > >its purpose > > > - instead we can beef up the _dotop sub of Stash to give us what we > > >want! > > > - Trained Stash to look for widgets by name and if found call their > > >"display" method with any parameters supplied in the template > > > > > > > > >testprg.pl > > >------------- > > >use Template; > > >use Widget::Test; > > > > > >my $tt=Template->new( { INCLUDE_PATH=>"." } ); > > > > > ># Ya get yer vermin whereever u want - XML, SQL, FooBar > > >$vars= { > > > 'widgets' => { > > > 'test1' => Widget::Test->new( maximum=>100, current=>10 ) > > > }, > > > 'lots' => 'o', > > > 'more' => 'variables', > > >}; > > > > > >$tt->process("test.html", $vars) || > > > die "Failed: ".$tt->error()."\n"; > > > >Hmmm. > >So the "widgets" entry in the stash becomes magic. > >Seems unattractive because you need to modify the Template Toolkit itself. > >But I every solution I can think of requires more steps in the Templates > >page than > >I'd like to see as well. > > > > >-------------- > > >test.html > > >-------------- > > >This is a test. <p> > > >[% test1 %] > > > >What do you see as the desirability of making the call program know about the > >widgets vs. making the template know about the widgets? > > > >I had envisioned some usage like... > > > > [% USE wc = Widget %] > > This is a test. <p> > > [% wc.test1 %] > > > >This would need some sort of Template Toolkit driver or a special controller > >for Template Toolkit to make the syntax work out this way. > > > > >-------------- > > >Patch to Template Toolkit 2.02 - Template/Stash.pm > > >-------------- > > > if (defined($value = $root->{ $item })) { > > > return $value unless ref $value eq 'CODE'; ## RETURN > > > @result = &$value(@$args); ## @result > > > } > > ># Whacked in widget handler > > > if (defined $root->{ 'widgets' } && defined > > >$root->{'widgets'}{$item}) { > > > return $root->{'widgets'}{$item}->display(@$args); > > > } > > ># /Whack > > > > > > elsif ($lvalue) { > > > # we create an intermediate hash if this is an lvalue > > > return $root->{ $item } = { }; ## RETURN > > > } > > > > > > >This is an interesting option. > >Please see if you can come up with a way which does not require us to > >modify the Template Toolkit to specifically recognize a "magic" variable > >in the stash. > > > >Stephen > > What it sounds to me is that rather than hacking TT in a specific way for > widgets, TT would benefit a lot from a generic taglib hook. > > In Java I am used to JSPs and we code widgets using taglibs. So the widgets > are objects, but then there is a widget taglib that can display a widget. > > <widget id='fname'/> > > in JSP parlance for example. So, for example, with Template Toolkit might we have something like: [% WIDGET fname %] Which would render the widget in place - and of course you could do things like [% WIDGET fname.value('Jay') %] if you wanted to set it in your template code. I don't know if it is being discussed but templates don't have a super friendly way of expressing named parameters. You can do things like [% WIDGET fname('value','Jay','colour','green','width','20') %] but it might be more attractive to have a syntax this is clearly name=>"value" or the like.... I guess the advantage here is that you can abstract how widgets are instanciated and potentially create efficiency by allowing for widget instanciation at the time the template is compiled... Jay |
From: Jay L. <Ja...@La...> - 2001-06-11 14:14:59
|
I think we can all safely say that XML is an application developer's choice and won't be part of the core Widget development effort - but rather an important side project if people want to use XML to create and control widgets. Agreed? Jay > My initial reaction is that I think this is much more complex than a widget > library that produces HTML and it's even less clear to me that XML is a > good delivery mechanism for abstracting forms. > > I truly believe that when you make an app into an HTML app vs a WML app vs > anything else that the screens are significantly different. > > I think that this XML stuff may be fine for content sites like newspapers, > but for an app it seems like it's a lot of work for much less gain than you > get on the pure content management side. > > Later, > Gunther > > At 10:49 PM 6/8/2001 +0100, Matt Sergeant wrote: > >Thought this might interest some of you widget geeks :-) > > > >-- > ><Matt/> > > > > /|| ** Founder and CTO ** ** http://axkit.com/ ** > > //|| ** AxKit.com Ltd ** ** XML Application Serving ** > > // || ** http://axkit.org ** ** XSLT, XPathScript, XSP ** > > // \\| // ** mod_perl news and resources: http://take23.org ** > > \\// > > //\\ > > // \\ > > > >---------- Forwarded message ---------- > >Date: Fri, 8 Jun 2001 22:40:56 +0100 (BST) > >From: Matt Sergeant <ma...@se...> > >To: AxKit Users Mailing List <axk...@ax...> > >Subject: XSP PerForm taglib > > > >Taking a bunch of ideas from a number of places I've started putting > >together what I call the "PerForm" taglib. This is sort of a magic form > >tag library that will enable you to write web forms sucking data from > >various sources more easily. > > > >I'm looking for some sort of feedback on this, though it's pretty funky as > >it stands IMHO. > > > >Best way to describe it is with an example (this assumes passing > >familiarity with XSP): > > > >=============== > > > ><?xml version="1.0"?> > ><xsp:page > > xmlns:xsp="http://apache.org/xsp/core/v1" > > xmlns:web="http://axkit.org/NS/xsp/webutils/v1" > > xmlns:f="http://axkit.org/NS/xsp/perform/v1" > > language="perl" > > indent-result="yes" > > > > ><!-- TOP LEVEL LOGIC --> > ><xsp:logic> > > > ># Each function recieves a $ctxt object, which is a hash to > ># store things in. It has one entry by default, "Form", which > ># is a hash of form values > > > >sub load_title { > > my ($ctxt, $default, $current) = @_; > > warn("load_title ($default, $current)\n"); > > return $current || $default; > >} > > > >sub load_link { > > my ($ctxt, $default, $current) = @_; > > warn("load_link ($default, $current)\n"); > > return $current || $default; > >} > > > >sub save_title { > > my ($ctxt, $new_value) = @_; > > warn("save_title : $new_value\n"); > >} > > > >sub save_link { > > my ($ctxt, $new_value) = @_; > > warn("save_link : $new_value\n"); > >} > > > >sub start_form_create { > > my ($ctxt, $save_mode) = @_; > > warn("start_form\n"); > >} > > > >sub end_form_create { > > my ($ctxt, $save_mode) = @_; > > warn("end_form\n"); > > # if everything is OK, and we're in save_mode, redirect. > > if ($save_mode) { > > if ($ctxt->{OK}) { > > # note mixing taglibs and Perl!!! > > <web:redirect uri="everything_ok.xsp"/> > > } > > } > >} > > > ></xsp:logic> > > > >Title: > >Link: > ></xsp:page> > > > >=============== > > > >OK, hopefully that hasn't confused anyone too much. Now the idea is that > >these forms always get submitted back to themselves. They do their own > >validation. If everything went well and the form got saved OK, they issue > >a redirect to another page. It's kinda like the MVC model, only slightly > >spiced the AxKit way :-) > > > >Now when the form is first loaded, the input fields are populated by a > >callback to the load_<name>() function, where <name> is the name entry of > >the particular form field. So to populate the first textfield, it calls > >load_title(...). It passes in parameters $ctxt, $default, and $current. > >Note that $current will only be filled if this form has already been > >submitted once (filled with the current value, obviously). The value you > >return is what goes in the text box that the user sees. > > > >When the form is submitted, the save_<name>() functions are called. This > >time they are passed the $ctxt and the new value. There you can do > >validation or whatever you like (save to a DB, etc). > > > >Each view of the form is started by a call to start_form_<name>(), where > ><name> this time is the name attribute on the form. When all the form's > >callbacks have been performed, the end_form_<name>() callback is called. > > > >The $ctxt object is a simple hashref that you can fill with whatever you > >like. It's there to help you maintain state between the callbacks. It > >contains one entry by default, "Form", which is a hashref to all the other > >form values. This allows you to do validation where one value depends on > >another. > > > >If you *don't* want to supply callbacks for load_*, then it defaults to > >using either the current value (i.e. the value last posted to the form), > >or the default value specified if this is the first load of this form. > > > >Now when all this has been done, it doesn't generate a HTML widget. It > >just generates some XML decorated with all the relevant attributes. You > >need to write an XSLT stylesheet (which I'll include with the package for > >HTML) to render it to HTML. But it's really simple to do that with > >xsl:include/xsl:import. I may even be persuaded to do an XPathScript > >stylesheet for it :-) > > > >I welcome your feedback on this. I think it will make building complex > >forms really easy. One nice thing with XML is we can put all that nasty > >callbacks code in another file, and use entities to load it in. Or we can > >use "use OtherPackage qw(...)" to import the functions to the current > >namespace. Either way will work. > > > >I can put this in CVS if people want to play with it as it stands. But I > >have only implemented the textfield widget as yet. > > > >-- > ><Matt/> > > > > /|| ** Founder and CTO ** ** http://axkit.com/ ** > > //|| ** AxKit.com Ltd ** ** XML Application Serving ** > > // || ** http://axkit.org ** ** XSLT, XPathScript, XSP ** > > // \\| // ** mod_perl news and resources: http://take23.org ** > > \\// > > //\\ > > // \\ > > > > > >--------------------------------------------------------------------- > >To unsubscribe, e-mail: axk...@ax... > >For additional commands, e-mail: axk...@ax... > > > > > > > >_______________________________________________ > >Perl-widget-developer mailing list > >Per...@li... > >http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > > __________________________________________________ > Gunther Birznieks (gun...@eX...) > eXtropia - The Open Web Technology Company > http://www.eXtropia.com/ > > > _______________________________________________ > Perl-widget-developer mailing list > Per...@li... > http://lists.sourceforge.net/lists/listinfo/perl-widget-developer > |
From: Jay L. <Ja...@La...> - 2001-06-11 14:12:06
|
> 1) I am wondering if [Perl-widget-developer] can be shortened to [pwdev] in > these messages. SUBJECT TAG CHANGE I have made a change in the subject tag based on Gunther's good suggestion. It will now read as [PW-dev]. REPLY-TO ADDRESS CHANGE In addition - I have changed the reply-to to be the list rather than the author. I am sure we can agree that most correspondance should go to the list by default. I personally don't want to see duplicate emails all the time either. If you don't like these changes please flame me directly and not on the list. :) Jay |
From: Matt S. <ma...@se...> - 2001-06-11 10:31:20
|
On Mon, 11 Jun 2001, Gunther Birznieks wrote: > My initial reaction is that I think this is much more complex than a widget > library that produces HTML and it's even less clear to me that XML is a > good delivery mechanism for abstracting forms. What XML gains you is parsability, so you can generate code easier when you just stick widgets on the form. > I truly believe that when you make an app into an HTML app vs a WML app vs > anything else that the screens are significantly different. Well that's fair enough, and you can do that too with this system. I believe you totally that WML and HTML forms are significantly different. The idea here though is to allow developers to use the same widget language for different forms. > I think that this XML stuff may be fine for content sites like newspapers, > but for an app it seems like it's a lot of work for much less gain than you > get on the pure content management side. I've changed the implementation a bit since I posted that, though you appear pretty set in stone about your ideas of a good widget system... So given a form as follows: <f:form name="mailinglist> <f:textfield name="email"/> <f:single-select name="type"/> <f:submit name="subscribe" value="Submit"/> <f:submit name="cancel" value="Cancel"/> </f:form> You can optionally (all functions are optional) supply the following subs: start_form_mailinglist end_form_mailinglist load_email validate_email load_type validate_type submit_subscribe submit_cancel I think (hope) the sub names are pretty self explanatory now. Each sub recieves a $ctxt object so you can maintain state. I'm thinking of including the form name in the widget callback subs somehow, so you can have widgets of the same name on the same page but in different forms. The return value of submit_* is a string that the library sends a redirect to. Anyway, this isn't the same goal as your Widget.pm library. You could never use that in AxKit/XSP because its designed very differently from any technology you are used to. So this is a simple way to do forms for people using AxKit, and I think it's a lot easier than the current methods (current methods available in AxKit/XSP, that is). Enjoy :-) -- <Matt/> /|| ** Founder and CTO ** ** http://axkit.com/ ** //|| ** AxKit.com Ltd ** ** XML Application Serving ** // || ** http://axkit.org ** ** XSLT, XPathScript, XSP ** // \\| // ** mod_perl news and resources: http://take23.org ** \\// //\\ // \\ |