[cgiapp] Param method?
I understand that the purpose of the param method is to give me a way to store variables in $self without potentially colliding with C::A's use of the same name. If that's correct, wouldn't it be easier just to choose a naming convention within C::A (perhaps a prefix: __C_A__) and document that users should not refer to anything in $self with this prefix? Then I wouldn't have to go through the param method to safely use store my variables in $self? I mean, isn't $self as much mine as it is C::A's? Why should C::A have exclusive access to it and force me to use a method to get to it? C::A is well-defined with a fixed role. Why can't it namespace itself and let me access $self however I want (as long as I stay away from that namespace)? Thanks, Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
There's also the added benefit that you can call params in list context to get an array containing all the information you have stored in params() which can make debugging a little bit easier. I understand that the purpose of the param method is to give me a way to store variables in $self without potentially colliding with C::A's use of the same name. If that's correct, wouldn't it be easier just to choose a naming convention within C::A (perhaps a prefix: __C_A__) and document that users should not refer to anything in $self with this prefix? Then I wouldn't have to go through the param method to safely use store my variables in $self? I mean, isn't $self as much mine as it is C::A's? Why should C::A have exclusive access to it and force me to use a method to get to it? C::A is well-defined with a fixed role. Why can't it namespace itself and let me access $self however I want (as long as I stay away from that namespace)? - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
That is making the assumption that C::A will always be implemented as a hash. The documentation says nothing about how C::A is implemented and therefore makes no guarantees that it won't be an array, or array of hashes, or anything else. Speaking of which, who wants to take the first stab at making the Perl 6 version of C::A? :) Michael -- Michael Graham [EMAIL PROTECTED] - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
From: Michael Peters [EMAIL PROTECTED] Not just that, but it also provides an easy way to pass variables between methods as well as communicating between plugins and other base classes. I'm not an OO guru. If I'm off base please forgive me. But, what's the difference between $self-param('var_name', 'var_value') and $self-var_name = 'var_value' The only thing I've heard is that I might collide with a var_name C::A uses. Wouldn't it be simpler to define C::A's variable names such that I would never collide with them? That is making the assumption that C::A will always be implemented as a hash. No. It's my $self, right? So, I can make any assumptions about how *I* implement myself, right? I subclassed C::A and I don't want to collide (or *access*) any of *its* variables. I can understand C::A making me use a setter/getter method to access *its* variables. But, why do I have to use one to access *my* variables? That's what I'm driving at. It may be good practice for me to use setter/getter methods for my own variables. But, why should C::A force me to use its method? Which looks better/cleaner? my $stuff = $self-param('stuff'); or my $stuff = $self-{__C_A__}-{stuff}; That's not quite what I was saying. I don't want to access C::A's hypothetically prefixed variables. What I was saying is that, if they were prefixed, I wouldn't have to worry about ever accidentally accessing them. If they were prefixed with __C_A__, I would have the freedom to choose whether to access $self with a setter/getter method or not. (The idea is that I *wouldn't* intentionally go around specifying __C_A__ all over the place.) I'm just saying isn't there a way to avoid clobbering C::A's variables without making me go through C::A's setter/getter method? Well, it is yours in the sense that you are subclassing it, but if you are using C::A then you *should* only be using the documented interface I agree. I'm just saying, couldn't it be documented that C::A's variables won't be clobbered if I access $self any way I want? Couldn't they be hidden away differently? Out of curiosity, why don't you like param()? It's a pretty well established idiom in the Perl community. Well, on the one hand we hear that Perl's strength is that you can do something a zillion different ways. :) So, I'm just asking why my $self is subordinated to C::A's use of it? Isn't there a way for C::A to semi-reserve its variables from my access and leave it up to me whether I want to access $self directly or through my own setter/getter methods, or a method C::A provides? I'm not arguing whether setter/getters are good or bad. Just why I'm forced to use C::A's. Why is that the only way to avoid stepping on C::A's variables? Thanks! Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
From: Andrew Brosnan [EMAIL PROTECTED] Just speaking generally about OO, I always figure it's dangerous to monkey with the object's underlying data structure. Might it change in the future? Who knows. I agree with that if I'm acessing C::A's underlying data structure. What I'm getting at is why does C::A force its underlying data structure upon me? Shouldn't I be able to access $self any way I want? Shouldn't there be a way to prevent me from stepping on C::A's data structure without forcing me to use its param method to get access to $self? My whole point is that I don't want to make assumptions about C::A's data structure. I don't want to know anything about it. But, I think I should have access to $self without having to use C::A's param method (to store my own instance variables) just to avoid C::A's data structure. It seems like I have to know more about it than I want. Wouldn't the problem be solved if C::A's variables were prefixed in such a way that, as long as I don't use that prefix, I wouldn't have to bother myself with C::A's param method? (If that's the only point of param). Thanks, Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
I'm not arguing whether setter/getters are good or bad. Just why I'm forced to use C::A's. Why is that the only way to avoid stepping on C::A's variables? It sounds like you want to rewrite the contract. Currently, the contract states if you use the param method and its implicit get/set method then we promise not to screw you up when you upgrade CGI::App to a new version. What you want it CGI::App promises to put its own variables in $self-{__somewhere_over_the_rainbow_*}, so if you want to put your variables in the $self-{_my_dad_can_beat_up_your_dad_*} namespace then you can do that and you're fine. The argument against this is basically that the contract you want makes the CGI::App authors promise to give you an underlying hashref implementation. That may not make sense in the future. It almost certainly won't make sense in a Perl 6 world (as Michael Graham was kind of getting at in his earlier email along these lines). This whole great divide is just one of the underlying premises behind object-oriented programming -- module (well, class) authors are responsible to module (well, class) users in terms of functionality, but not in terms of how it achieves the functionality. In almost any other mainstream language other than Perl no-one would ever want to try to do what you want, nor would they even *contemplate* being able to do this, because the underlying implementation is so opaque to derived classes that there's basically no way to get at the underlying data structure. In Perl 5 the underlying data structure is *so* close to the interface that module users *always* want to be able to do this, and then their scripts *always* break when they upgrade to the latest version of the module because the module author changed something. Cheers, Richard - This mail sent through IMP: http://horde.org/imp/ - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
On 7/4/05 at 2:06 PM, [EMAIL PROTECTED] (Mark Fuller) wrote: From: Michael Peters [EMAIL PROTECTED] Not just that, but it also provides an easy way to pass variables between methods as well as communicating between plugins and other base classes. I'm not an OO guru. If I'm off base please forgive me. But, what's the difference between $self-param('var_name', 'var_value') and $self-var_name = 'var_value' Use something like DataDumper to print out the object and you'll see. use Data::Dumper; print Dumper($self); You're making an assumption about the underlying data structure, and may be surprised at the result :-) That is making the assumption that C::A will always be implemented as a hash. No. It's my $self, right? ... But, why should C::A force me to use its method? I think that's pretty typical OO encapsulation and also the point here. Andrew - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
Mark Fuller wrote: From: Michael Peters [EMAIL PROTECTED] Not just that, but it also provides an easy way to pass variables between methods as well as communicating between plugins and other base classes. I'm not an OO guru. If I'm off base please forgive me. But, what's the difference between $self-param('var_name', 'var_value') and $self-var_name = 'var_value' Well, first off, you can't do the second one. It would only work if you made a method named 'var_name' that would act like a setter/getter (or use the :lvalue method attribute). So you would need to compare $self-param(var_name = 'var_value') to $self-{var_name} = 'var_value'; It's basically the difference between using a hashref and using an object. If you have an object, then why not use OO? If all you have is a hash, then by all means use it as a hash. But that's not what you have. The only thing I've heard is that I might collide with a var_name C::A uses. Wouldn't it be simpler to define C::A's variable names such that I would never collide with them? C::A never putts anything in param(). It's just for your use. That is making the assumption that C::A will always be implemented as a hash. No. It's my $self, right? So, I can make any assumptions about how *I* implement myself, right? I subclassed C::A and I don't want to collide (or *access*) any of *its* variables. I can understand C::A making me use a setter/getter method to access *its* variables. But, why do I have to use one to access *my* variables? No, that's just it. By using C::A as a base class, the $self is what C::A decides it is, not you. The only way you could decided fo yourself is to use a 'HAS A' (delegation) relationship with C::A, not an 'IS A' (inheritance) and that would be extremely messy. That's what I'm driving at. It may be good practice for me to use setter/getter methods for my own variables. But, why should C::A force me to use its method? C::A only forces you because you chose to use it as your base class. That's not quite what I was saying. I don't want to access C::A's hypothetically prefixed variables. What I was saying is that, if they were prefixed, I wouldn't have to worry about ever accidentally accessing them. If they were prefixed with __C_A__, I would have the freedom to choose whether to access $self with a setter/getter method or not. (The idea is that I *wouldn't* intentionally go around specifying __C_A__ all over the place.) Once again, *C::A doesn't put anything into param()*. It's just for your use. Where it puts it's own variables is it's own business. I agree. I'm just saying, couldn't it be documented that C::A's variables won't be clobbered if I access $self any way I want? Couldn't they be hidden away differently? Well, that's sort of the point of documenting the interface is that you don't document the internals. They are no ones business but the author's. Well, on the one hand we hear that Perl's strength is that you can do something a zillion different ways. :) So, I'm just asking why my $self is subordinated to C::A's use of it? Isn't there a way for C::A to semi-reserve its variables from my access and leave it up to me whether I want to access $self directly or through my own setter/getter methods, or a method C::A provides? I agree that there is usually more than one way to do it. That doesn't mean that there's more than one 'right' way to do it :) And it also means that modules authors don't have to provide more than one. If you want to store your stuff in the $self blessed hash, then go ahead and do it. But why should the C::A author change his interface and document his internals when there is already a provided way to do it? -- Michael Peters Developer Plus Three, LP - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
I agree with that if I'm acessing C::A's underlying data structure. What I'm getting at is why does C::A force its underlying data structure upon me? Shouldn't I be able to access $self any way I want? Shouldn't there be a way to prevent me from stepping on C::A's data structure without forcing me to use its param method to get access to $self? It's not about stepping on CGI::App. It's about that you're making expecations of what CGI::App is giving you to work with. My whole point is that I don't want to make assumptions about C::A's data structure. But you are! You want to be able to access $self-{foobar} without recrimination, but where did $self-{...} come from in the first place? The mere fact that $self-{...} exists in an artifact of that CGI::Application's underlying implimentation is built upon a blessed hash reference. 'foobar' may be yours, but $self-{...} comes from CGI::Application. - This mail sent through IMP: http://horde.org/imp/ - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
Mark Fuller wrote: No. It's my $self, right? So, I can make any assumptions about how *I* implement myself, right? I subclassed C::A and I don't want to collide (or *access*) any of *its* variables. I can understand C::A making me use a setter/getter method to access *its* variables. But, why do I have to use one to access *my* variables? That's what I'm driving at. It may be good practice for me to use setter/getter methods for my own variables. But, why should C::A force me to use its method? This is the problem. It's not your $self. You didn't bless it into being an object. Technically the $self is owned by whoever blessed it. So, since you are *inheriting* from C::A and assuming you aren't sub-class it's new() method, then C::A owns $self. Inheritance is the key. You do not simple use C::A in your packages, you inherit ( use base ) from it, thus, you are expected to abide by the ground-rules set out by the parent class, anything less and you risk your application breaking in the future when you upgrade. If you are creating your own objects with your own new() methods that are blessing objects into existence, then you can control $self however you want, but Andrew was right, $self may not be a hash, it could be an array, and it could be something very different in Perl 6. -- Steve Comrie - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
On 7/4/05, Mark Fuller [EMAIL PROTECTED] wrote: From: Michael Peters [EMAIL PROTECTED] Not just that, but it also provides an easy way to pass variables between methods as well as communicating between plugins and other base classes. I'm not an OO guru. If I'm off base please forgive me. But, what's the difference between $self-param('var_name', 'var_value') and $self-var_name = 'var_value' The only thing I've heard is that I might collide with a var_name C::A uses. Wouldn't it be simpler to define C::A's variable names such that I would never collide with them? There are a couple of ways of looking at this. Internally, C::A first converts the keys to UPPER_CASE before performing a lookup or store operation. If C::A then was to store the variables as object properties (which it doesn't; they're stored in the _PARAMS object property), you could then be certain that any properties named in lowercase or in camelCase wouldn't conflict with any stored using the param() method. Now, you say, the only thing I've heard is that I might collide with a var_name C::A uses. That's not the whole picture. The param() method is called during object instantiation, and loads any items in the PARAMS key passed to the constructor. This allows you to customize an application based on the PARAMS passed in the instance script -- which is pretty powerful. This is my primary use for the param() method -- application customization. It doesn't really matter how param() stores the variables; I simply know that they're available via that method. That is making the assumption that C::A will always be implemented as a hash. No. It's my $self, right? I may be reading you wrong, but the variables stored via param() are *not* (at least last I checked; I haven't downloaded the 4.x series yet) stored in $self; they're in the $self-_PARAMS hash. So, I can make any assumptions about how *I* implement myself, right? I subclassed C::A and I don't want to collide (or *access*) any of *its* variables. I can understand C::A making me use a setter/getter method to access *its* variables. But, why do I have to use one to access *my* variables? That's what I'm driving at. It may be good practice for me to use setter/getter methods for my own variables. But, why should C::A force me to use its method? It doesn't. You can mix and match. The main purpose of param(), as I noted above, is to allow the instance script to setup the object environment. Properties that you don't want controlled in this way don't need to be. For instance, I often place my database handle in $self-db -- which isn't accessible via the param() method. -- Matthew Weier O'Phinney [EMAIL PROTECTED] http://weierophinney.net/matthew/ - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
From: Michael Peters [EMAIL PROTECTED] If you want to store your stuff in the $self blessed hash, then go ahead and do it. Wait. That sounds like what I'd like to do. Is there a way I can bless my own sliver of $self and store my own data structure there without trampling on C:A's use of $self (and without being required to use its method to access its data strcuture)? Can I have my own data structure? I'm sorry I stirred up such a discussion. It's probably my ignorance. Thanks, Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
On 7/4/05, Mark Fuller [EMAIL PROTECTED] wrote: From: Michael Peters [EMAIL PROTECTED] If you want to store your stuff in the $self blessed hash, then go ahead and do it. Wait. That sounds like what I'd like to do. Is there a way I can bless my own sliver of $self and store my own data structure there without trampling on C:A's use of $self (and without being required to use its method to access its data strcuture)? Can I have my own data structure? I'm sorry I stirred up such a discussion. It's probably my ignorance. No need to be sorry. You didn't stir anything up. What you did is start some healthy discussion, and I think it has turned into a discussion that many people can learn from. I hear you when you say you just want to use $self and do with it what you want. Personally I think it is often OK, as long as you know all of the pitfalls that come with it, so that you will not be surprised when it breaks down in front of your eyes. Really there are only two main concerns: 1. You need to make sure that you use your own namespace so as not to collide with anyone else. You suggested that CGI::App use __C_A__ as a prefix, but it really should be you that uses a prefix. Perhaps __M_F__ to use your prefix style. There is a good chance that no one else (plugin authors and such) will use that prefix. So if you access it directly, use $self-{__M_F__var1} or $self-{__M_F__}-{var1} 2. The author of CGI::Application may decide that $self is no longer going to be a hashref, and instead is going to use inside-out objects, or an arrayref or something else. This is the one that everyone always brings up. I would like to state that this is almost never going to happen (I know, famous last words). But it is important to know that it can happen, which means you need to be more careful about upgrading to new versions of CGI::App. That is a tradeoff you have to make. You have another option as well that could work for you, and would be implemented cleanly and wouldn't throw up any red flags. Create accessors for all your variables and have these accessors use the -param method. # Custom param method to hide the new namespace sub my_param { my $self = shift; my $key = shift; my $value = shift; $self-param('__M_F__'.$key = $value) if defined $value; $self-param('__M_F__'.$key); } sub var1 { my $self = shift; return $self-my_param('var1' = @_); } sub var2 { my $self = shift; return $self-my_param('var2' = @_); } Then you can access them like this: my $var = $self-var1; $self-var1('new value'); I'm sure you could improve upon that in some way, but at least it shows a way that will allow you to easily add your own parameters to your subclass without needing to worry about the underlying architecture. Of course you can choose to ignore all the advice on the list as well, and just access $self directly (I have been known to do it as well). It is really up to you. Just make sure you know the consequences of those decisions. Cheers, Cees - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
Following are replies to Dan and Andrew: From: Dan Horne [EMAIL PROTECTED] It seems to me that the namespace issue is problematic. ... but what if I unknowingly wrote a plugin that uses the same attribute, From what I gather, plug-ins rely upon a namespace mechanism C::A recommends. Why can't applications extending C::A have a similar namespace? What if C::A made a hash ref available for application use? Something like $self-{appl{}} which would be available to the application extending C::A? Someone else alluded to overriding C:A's new method and that this would allow control of how $self is created? I could have a $self and access how I like? And a part of it would be C:A's which I would access how C::A dictates? Do you know how that is done? That's what I'm getting at. I can understand I must access C::A how it dictates. But, I'm extending C::A. Why can't I have my own area to access however I want. And, if I choose not to use setter/getter routines (for performance reasons?) it shouldn't be a problem since my extension of the class is my own extension and I should be able to be subject myself to my own coding? From: Andrew Brosnan [EMAIL PROTECTED] I used to think along the same lines as you. Then this guy named Damian set my a$$ straight ;-). He had a pretty good book out: 'Object Oriented Perl' from Manning. Sam Tregar made the same suggestion to me a few months ago. I will make more of any effort to get the book and read it. Thanks, Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: [cgiapp] Param method?
From: Cees Hek [EMAIL PROTECTED] 1. You need to make sure that you use your own namespace so as not to collide with anyone else. You suggested that CGI::App use __C_A__ as a prefix, but it really should be you that uses a prefix. If C::A provided the namespace, wouldn't this reduce the chances of colliding with others who may use that namespace? (And maybe reduce the chance of $self changing and breaking my access to it as $self-{__MF__my_var}? If C::A guaranteed that there would always be a $self-{appl} which could be used as a hash reference, couldn't I safely access $self-{appl{my_var}}? I'd never have to worry about C::A or a plug-in using appl. And, if C:A produced a different object (in the future), it could still make a hash available for backward compatibility? It may be six of one, half-dozen of the other. But, it seems to me that C::A should be the one prefixing all its variables as __C_A__ so that it is transparent to the applications extending C:A? If you have the choice between thousands of users having to prefix their variables, or C:A doing it, wouldn't it make sense for C:A to do it? I suppose plug-ins would simply extend the prefix? (__C_APlug_in__). That would be behind the scenes. The person using C::A wouldn't need to know about it. They could access the hash any way they want? The next best step (IMO) would be a hash key (like appl) which is agreed to never be used by C::A or any plug ins. It wouldn't be as transparent. But, not as risky as anyone choosing their own prefix (like __MF__). Thanks, Mark - Web Archive: http://www.mail-archive.com/cgiapp@lists.erlbaum.net/ http://marc.theaimsgroup.com/?l=cgiappr=1w=2 To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]