Graciliano,

I like it. I could offer a few suggestions, as source filtering has been my recent interest.

The first question I have...What is "HPL"? That puzzled me the most, and I don't believe it is at all obvious.

Second, the POD might include a section on the rationale for the syntax chosen since there are many possible alternatives. Given that there is already at least one alternative module (Perl6::Classes), the potential user of this module would like to know when Class::HPLOO should be chosen over another. Is the reason purely that Class::HPLOO is more robust as stated? (Which is believable since Perl source filtering is tricky, although I haven't used either sufficiently to confirm.) If so, Perl6::Classes itself could be fixed. Or is there a reason to use a syntax other than that of Perl6 (e.g. to be more Perl5-like or Java-esque, for those more familiar with Java)? If so, the module might be renamed something like Class::Javaesque to reflect that.

The semantics "return 0 makes the creation of the object return undef" can be prone to nonobvious errors. For example, looking at your included classtest.pm example,

  class Foo extends Bar , Baz {
    sub Foo {
      $this->{attr} = $_[0] ;
    }
    ...
  }

If I do

my $x = new Foo(1);

properly sets $x to reference an instance of Foo, but

my $x = new Foo(0);

causes $x to be set to undef since the line "$this->{attr} = $_[0]" evaluates to 0 and becomes the return value. If the module author made this error, the user will too. The typical thing to do, at least in Java, is to throw an exception ("die") inside the constructor if it is to fail (or not let constructors do anything that can fail). That's one option, but I'm not suggesting it must be done that way.

Next, the POD can be clearer about which parameter passing methods are used. For example, does

  class Baz {
    sub test(\%val) { $val{one}='two'; }
  }
  my %x;
  (new Baz())->test(\%x);

modify %x? My first intuition on seeing the "\%val" syntax is that the hash is passed by reference, so it would be modified. On further look, I think my original understanding is wrong (i.e. \%x should be understood as a list of named input parameters, not an arbitrary hashref to pass in--this can be documented in the POD). Another option would be to mimic Perl-6-like prototypes (e.g. see Perl6::Parameters).

Looking at the actual code, you might want to use the /x switch with whitespace on the regexs and limit line lengths to 80 characters for improved clarity + four character indenting. See this recent perl.com article for details:

  Maintaining Regular Expressions, by Aaron Mackey
  http://www.perl.com/pub/a/2004/01/16/regexps.html

as well as

http://www.perldoc.com/perl5.8.0/pod/perlstyle.html

best regards,
-davidm

Graciliano M. P. wrote:
I have just released the module Class::HPLOO, that anables the well know
style for class declaration in Perl.

But I want know if already exists another filter that implements that, since
I have looked and haven't found anything about, only Perl6::Classes that
doesn't work very well, since is very easy to write a code that breaks the
filter.

For me is much more easier to create a Perl Module with Class::HPLOO, since
I just tell the class name and the methods, and all the OO code that I need
to write is automatically done. Than I can run it as it was, or I can
convert it to a normal Perl Module file, not dependent to the filter.

You can get it at:
http://search.cpan.org/~gmpassos/

But I want to know what the other module author think about it, since this
is a tool for us?

Just some example of syntax:

use Class::HPLOO ;

class Foo extends Bar , Baz {

vars ($VERSION , $GLOBAL_PUBLIC) ;

$VERSION = '0.01' ;

my $GLOBAL_PRIVATE ;

    ## Initializer (called by default new):
    sub Foo (%args)

      $this->{X} = $args{x} ;
      $this->{Y} = $args{y} ;
    }

    sub x { $this->{X} }
    sub y { $this->{Y} }

    sub test_args ($x , $y , \%opts , [EMAIL PROTECTED] , $more ) {
      print ">> $x\n" ;
      print ">> $y\n" ;

my @keys = map { $_ => 1 } (keys %opts , @list) ;

      print ">> $more\n" ;
    }

    sub old_style {
      my ( $x , $y ) = @_ ;
      print ">> $x , $y\n" ;
    }

    sub test_html_block {
      print <% html_foo>( $this->x , $this->y ) ;
    }

    <% html_foo($x , $y)
      <hr>
      X: $x , Y: $y
      <hr>
    %>

}

And this will produce this PM code:

{ package Foo ;

use vars qw(@ISA) ; push(@ISA , qw(Bar Baz UNIVERSAL)) ;

sub new

      my $class = shift ;
      my $this = bless({} , $class) ;
      my $ret_this = $this->Foo(@_) if defined &Foo ;
      $this = $ret_this if ( UNIVERSAL::isa($ret_this,$class) ) ;
      $this = undef if ( $ret_this eq '0' ) ;
      return $this ;
    }

sub CLASS_HPLOO_HTML

      return '' if !$CLASS_HPLOO_HTML{$_[0]} ;
      no strict ;
      return eval( ${$CLASS_HPLOO_HTML{$_[0]}}[0] . " <<CLASS_HPLOO_HTML;
      \n". ${$CLASS_HPLOO_HTML{$_[0]}}[1] ."CLASS_HPLOO_HTML\n" .
(shift)[1]) if ( ref($CLASS_HPLOO_HTML{$_[0]}) eq 'ARRAY' ) ;
      return eval("<<CLASS_HPLOO_HTML;
      \n". $CLASS_HPLOO_HTML{$_[0]} ."CLASS_HPLOO_HTML\n" . (shift)[1] ) ;
    }


use vars qw($VERSION $GLOBAL_PUBLIC) ;


$VERSION = '0.01' ;

my $GLOBAL_PRIVATE ;

sub Foo

      my $this = shift ;
      my %args = @_ ;
      @_ = () ;

      $this->{X} = $args{x} ;
      $this->{Y} = $args{y} ;
    }

    sub x { my $this = shift ; $this->{X} }
    sub y { my $this = shift ; $this->{Y} }

sub test_args

      my $this = shift ;
      my $x = shift(@_) ;
      my $y = shift(@_) ;
      my %opts = ref($_[0]) eq 'HASH' ? %{ shift(@_) } : ( ref($_[0]) eq
'ARRAY' ? @{ shift(@_) } : shift(@_) ) ;
      my @list = ref($_[0]) eq 'ARRAY' ? @{ shift(@_) } : ( ref($_[0]) eq
'HASH' ? %{ shift(@_) } : shift(@_) ) ;
      my $more  = shift(@_) ;

      print ">> $x\n" ;
      print ">> $y\n" ;

my @keys = map { $_ => 1 } (keys %opts , @list) ;

      print ">> $more\n" ;
    }

sub old_style

my $this = shift ;

      my ( $x , $y ) = @_ ;
      print ">> $x , $y\n" ;
    }

sub test_html_block

my $this = shift ;

      print CLASS_HPLOO_HTML('_foo',( $this->x , $this->y )) ;
    }

  $CLASS_HPLOO_HTML{'_foo'} = [ q`my $x = shift(@_) ;my $y = shift(@_) ;` ,
<<'CLASS_HPLOO_HTML' ];
      <hr>
      X: $x , Y: $y
      <hr>

CLASS_HPLOO_HTML

}

1;

The best thing is to handle automatically the arguments of the method,
specially when you want HASH or ARRAY references, what cut off some hard
code.

I also use this to introduce Perl developers that don't know very well OO in
Perl, but know in Java, to the OO development, since everything that we
develope need to be in OO style.

Regards,
Graciliano M. P.







Reply via email to