Re: Module Proposal: Package::Data::Inheritable
nntp.perl.org wrote: Hello all. I've written a module to deal with the issue of inheritable class data (yes, yet another one). What's peculiar with it is that it doesn't rely on accessor methods. After declaration, you can use the variables just like any other package variable but you can inherit and override those variables in other packages/classes. I'm thinking of calling the module Package::Data::Inheritable which should reflect the emphasis on package variables rather than on classes. Before uploading to CPAN I would like to check whether I missed some module that does the same and if the proposed name/namespace is good. Not sure what you're trying to do. Is it this? package A; our $DATA = 'A'; package B; use base 'A'; our $DATA = 'B'; package C; use base 'A'; And then: $A::DATA # 'A' $B::DATA # 'B' $C::DATA # 'A' If so, I don't know of anything on CPAN that does this. However, I think inheriting variables is a *terrible* idea. What is your reason for wanting to use variables instead of properly delegating to methods? Regards, Jonathan Rockway signature.asc Description: OpenPGP digital signature
Re: Module Proposal: Package::Data::Inheritable
Oops. Sent privately instead of to the list. Resending. --- nntp.perl.org [EMAIL PROTECTED] wrote: I've written a module to deal with the issue of inheritable class data (yes, yet another one). What's peculiar with it is that it doesn't rely on accessor methods. After declaration, you can use the variables just like any other package variable but you can inherit and override those variables in other packages/classes. Hi Giacamo, Hey, this idea sounds very cool, but unfortunately, it's a bad idea (conceptually similar to Java's mistake of allowing public properties). Here's an example, using some pseudo-code which assumes that Universe exports class data named '$pi': use Universe ($pi); my $universe = Universe-new('standard'); print $pi;# 3.14 ... $pi = -13;# What? print $pi;# -13 The problem with public properties instead of methods is that you cannot easily validate them at the time of setting the value. Sure, you can tie the variable, but why go through all of that work for a single value? Just make a setter/getter and you can validate it. Admittedly, Class::Data::Inheritable doesn't validate it, but you can do this: use base 'Class::Data::Inheritable'; __PACKAGE__-mk_classdata( _pi = 3.14 ); sub pi { my $self = shift; return $self-_pi unless @_; my $pi = shift; # make sure $pi is a valid number or die, die, die $self-_pi($pi); return $self; } Now you get nice safety and don't have to worry about things. Later, if you find your universe needs to calculate the value of pi (presumably by making an RPC call to another universe), you still have a nice method encapsulating this and don't have to change the public interface. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: Module Proposal: Package::Data::Inheritable
Jonathan Rockway ha scritto: nntp.perl.org wrote: Hello all. I've written a module to deal with the issue of inheritable class data (yes, yet another one). What's peculiar with it is that it doesn't rely on accessor methods. After declaration, you can use the variables just like any other package variable but you can inherit and override those variables in other packages/classes. I'm thinking of calling the module Package::Data::Inheritable which should reflect the emphasis on package variables rather than on classes. Before uploading to CPAN I would like to check whether I missed some module that does the same and if the proposed name/namespace is good. Not sure what you're trying to do. Is it this? package A; our $DATA = 'A'; package B; use base 'A'; our $DATA = 'B'; package C; use base 'A'; And then: $A::DATA # 'A' $B::DATA # 'B' $C::DATA # 'A' Yes, this is what is does (with some extra boilerplate code). If so, I don't know of anything on CPAN that does this. However, I think inheriting variables is a *terrible* idea. What is your reason for wanting to use variables instead of properly delegating to methods? This is common practice in other well known OO languages like C++ and Java. In fact the module implements that very kind of class data semantic. I'm aware that you loose encapsulation with package variables, but convenience of use sometimes comes first to me. A typical case I feel the need for that is when you have a hierarchy of classes where you deal with a lot of data fields and you name them with class data members: our FIELDNAME1 = 'field1'; our FIELDNAME2 = 'field2'; ... our FIELDNAMEn = 'fieldn'; and then you use them like this: foo({param1 = $val, fields = { $FIELDNAME1 = $val1, $FIELDNAME2 = $val2, ... $FIELDNAMEn = $valn, }, }); ... foreach my $field ($FIELD4, $FIELD2, ..., $FIELD10) { ... With accessor methods this would be considerably more verbose: foo({param = $val, fields = { $SomeClass-FIELDNAME1 = $val1, $SomeClass-FIELDNAME2 = $val2, ... $SomeClass-FIELDNAMEn = $valn, }, }); ... foreach my $field ($SomeClass-FIELD4, $SomeClass-FIELD2, ..., $SomeClass-FIELD10) { ... This becomes quickly unreadable and is not lazy. Furthermore every fieldname access is a method call which is too much overhead, especially when you have many fields to deal with. regards, Giacomo Regards, Jonathan Rockway
Re: Module Proposal: Package::Data::Inheritable
--- Giacomo Cerrai [EMAIL PROTECTED] wrote: With accessor methods this would be considerably more verbose: foo({param = $val, fields = { $SomeClass-FIELDNAME1 = $val1, $SomeClass-FIELDNAME2 = $val2, ... $SomeClass-FIELDNAMEn = $valn, }, }); ... foreach my $field ($SomeClass-FIELD4, $SomeClass-FIELD2, ..., $SomeClass-FIELD10) { ... This becomes quickly unreadable and is not lazy. Furthermore every fieldname access is a method call which is too much overhead, especially when you have many fields to deal with. A couple of problems here. Yes, methods can sometimes be more verbose than variables, but Java made a huge mistake by violating encapsulation. However, at least in Java you get a little bit of type safety (not much, but some). It's important to optimize for correctness first. Readability *must* come after correctness because if a program is incorrect, whether or not it's legible is small consolation. Also, if you're doing a huge amount of work with basic getter/setters, perhaps revisiting your object heirarchy is worthwhile. The more I've learned about OO, the more I've learned that it's about behaviors, not about data. Looking at data instead of behaviors can really hamper effectiveness in OO systems because you become tied to the data when what you really want is modeling of your problem domain's rules. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/
Re: Module Proposal: Package::Data::Inheritable
On 9/4/07, Giacomo Cerrai [EMAIL PROTECTED] wrote: A typical case I feel the need for that is when you have a hierarchy of classes where you deal with a lot of data fields and you name them with class data members: our FIELDNAME1 = 'field1'; our FIELDNAME2 = 'field2'; ... our FIELDNAMEn = 'fieldn'; and then you use them like this: foo({param1 = $val, fields = { $FIELDNAME1 = $val1, $FIELDNAME2 = $val2, ... $FIELDNAMEn = $valn, }, }); ... foreach my $field ($FIELD4, $FIELD2, ..., $FIELD10) { ... With accessor methods this would be considerably more verbose: foo({param = $val, fields = { $SomeClass-FIELDNAME1 = $val1, $SomeClass-FIELDNAME2 = $val2, ... $SomeClass-FIELDNAMEn = $valn, }, }); ... foreach my $field ($SomeClass-FIELD4, $SomeClass-FIELD2, ..., $SomeClass-FIELD10) { ... This becomes quickly unreadable and is not lazy. Furthermore every fieldname access is a method call which is too much overhead, especially when you have many fields to deal with. If you put the field names into an array (or hash) then it becomes a lot easier. our @FIELDNAMES = ( ... ); sub fieldnames { @FIELDNAMES }; my %fields; my @names = $SomeClass-fieldnames(); @[EMAIL PROTECTED] = ($val1, $val2, ..., $valn); foo({param1 = $val, fields = \%fields ); ... foreach my $field (@{$SomeClass-fieldnames()}) { ...
Re: Module Proposal: Package::Data::Inheritable
Ovid ha scritto: --- Giacomo Cerrai [EMAIL PROTECTED] wrote: With accessor methods this would be considerably more verbose: foo({param = $val, fields = { $SomeClass-FIELDNAME1 = $val1, $SomeClass-FIELDNAME2 = $val2, ... $SomeClass-FIELDNAMEn = $valn, }, }); ... foreach my $field ($SomeClass-FIELD4, $SomeClass-FIELD2, ..., $SomeClass-FIELD10) { ... This becomes quickly unreadable and is not lazy. Furthermore every fieldname access is a method call which is too much overhead, especially when you have many fields to deal with. A couple of problems here. Yes, methods can sometimes be more verbose than variables, but Java made a huge mistake by violating encapsulation. However, at least in Java you get a little bit of type safety (not much, but some). Just one note. It's not clear from my post, I should have put a 'package SomeClass' or $self-foo but the code above is in-class code, not meant as client code (although you cannot prevent that). It's important to optimize for correctness first. Readability *must* come after correctness because if a program is incorrect, whether or not it's legible is small consolation. Also, if you're doing a huge amount of work with basic getter/setters, perhaps revisiting your object heirarchy is worthwhile. The more I've learned about OO, the more I've learned that it's about behaviors, not Sorry again, I probably chose a wrong example. I never do heavy get/set inside class hierarchies, and do almost no get/setting at all from client code, it would be wrong. The FIELDNAMEs above are names of fields that your class code uses to refer to fields inside private data structures. You rarely set them, and nobody outside the class (or subclasses) should ever even get them. about data. Looking at data instead of behaviors can really hamper effectiveness in OO systems because you become tied to the data when what you really want is modeling of your problem domain's rules. Since I agree with your comments it means I've not been clear regarding the purpose of the module. I totally agree with using accessor methods for class members in general. In fact this is what I myself do most of the times. Sometimes though, I use both accessor methods and package variables. This module is meant for those times when I rely on package vars. - Syntax convenience and time efficiency The data I'm talking about are mostly logically constant data, which you access very often and multiple times in the same statement. Maybe you're crunching a db dump and speed matters. I wish I could state those datamembers are 'really' constant, for cleaness and efficiency, my module doesn't do that of course. use constant is not an option either. It does not allow for inheritance (access via object methods to those constants is not ok for the same reasons i'm putting forward) and you loose on the syntax far too often. You cannot interpolate into strings, cannot slice arrays and subscript hashes with the standard syntax. - It's a different approach Apart from this, I think it would be cool and why not, reasonable, to be able to inherit package variables. Sometimes it can be useful, just don't misuse the feature. regards, Giacomo Cheers, Ovid
Re: Module Proposal: Package::Data::Inheritable
nntp.perl.org wrote: Hello all. I've written a module to deal with the issue of inheritable class data (yes, yet another one). What's peculiar with it is that it doesn't rely on accessor methods. After declaration, you can use the variables just like any other package variable but you can inherit and override those variables in other packages/classes. I'm thinking of calling the module Package::Data::Inheritable which should reflect the emphasis on package variables rather than on classes. Before uploading to CPAN I would like to check whether I missed some module that does the same and if the proposed name/namespace is good. Sounds like a bad idea to me. mainly because you do not explain what you want to achieve and why you want to achieve it that way. the explainations have been too 'high level' for _me_ to understand. In another mail you explain that you ccan't use constants but the excellent Readonly module does what you want. Nadim.
Re: Module Proposal: Package::Data::Inheritable
--- Giacomo Cerrai [EMAIL PROTECTED] wrote: Just one note. It's not clear from my post, I should have put a 'package SomeClass' or $self-foo but the code above is in-class code, not meant as client code (although you cannot prevent that). Ah, this is for internal use only? OK then. The downside significantly less than I thought. Feel free to disregard a lot of what I said :) Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Perl and CGI - http://users.easystreet.com/ovid/cgi_course/ Personal blog - http://publius-ovidius.livejournal.com/ Tech blog - http://use.perl.org/~Ovid/journal/