Re: Module Proposal: Package::Data::Inheritable

2007-09-04 Thread Jonathan Rockway
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

2007-09-04 Thread Ovid
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

2007-09-04 Thread Giacomo Cerrai

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

2007-09-04 Thread Ovid
--- 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

2007-09-04 Thread Bill Ward
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

2007-09-04 Thread Giacomo Cerrai

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

2007-09-04 Thread nadim khemir
 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

2007-09-04 Thread Ovid
--- 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/