=head1 NAME Class::Tidy -- class members easy access, hiding @_, autoprototyping =head1 SYNOPSIS use Class::Tidy; meth mymethod( $a \@b ; $c ) { .val = $a; .meth(@b); .&funval(); } sub mysub ( $a ) { } translates into sub mymethod($\@;$) { my ( $self, $a, $b, $c ) = @_; $self->{a} = $a; $self->meth( @b ); $self->{funval}->(); sub mysub($) { my ( $a ) = @_; =head1 DESCRIPTION =head2 classmembers easy access C++ uses struct to implement class objects. The closest Perl relative is hash based classes. The values associated to keys are data member. Syntax to access these data members is ugly. Class::Tidy makes hash based classes less tedious to use by defining a simpler syntax for accessing the hash values, there is no runtime overhead. Compare with many Perl packages like Class::Struct or Class::Accessor provide accessors and mutators. Perl is interpreted and provides no inlining mechanism so shemes that provides accessor for accessing hash/member values has high overhead. =head2 hiding @_, autoprototyping Defining subroutines in perl with prototype is somewhat reminiscent of K&R C . There is a double take to fully define a parameters: In perl sub mymethod($\@;$) { # first take: prototypes my ( $self, $a, $b, $c ) = @_; # second take: affectation from @_ In K&R C double inner(v1, v2, n) /* first take: name the parameters */ double v1[], v2[]; /* second take: define them */ { ... } (from the C manual, http://www.cs.bell-labs.com/who/dmr/cman.ps, comments are mine) the keyword meth is introducted to indicate a method meth mymethod( $a \@b ; $c ) { sub mymethod($\@;$) { my ( $self, $a, $b, $c ) = @_; =head1 SOON IN A CPAN NEAR YOU encapsulation. Need a way to declare class data members, their types and who can access the members and how Type control will be made at compile time when possible and run-time in debug mode .@a = fun(); # means expect a reference to array (run time check) .@a = [ ]; # ditto (compile time check) @.a # dereference as an array =cut # package Class::Tidy; # use Filter::Simple; $_=<<'EOF'; # test case use Class::Tidy; meth mymethod( $a \@b ; $c ) { .val = $a; .meth(@b); .&funval(); } sub mysub ( $a ) { } EOF my $subnmqr = qr|\w+(?:::\w+)?|; # to support my dirty style of "drop-in methods" sub trans { s/ \s\.(\w+)\( /\$self->$1(/gxs; s/ \s\.(\w+) /\$self->{$1}/gxs; s/ \s.\&(\w+)\( /&{\$self->{$1}}(/gxs; s/ meth\s+($subnmqr)\s*\((.*?)\)\s*\{ / sub $1( \$self $2 ) { /sgx; s# sub\s+($subnmqr)\s*\((.*?)\)\s*{ # my ($subnm, $paras) = ($1, $2); my ($mandparas, $optparas ) = split ';', $paras; $mandparas =~ s/\s*(.*?)\s*/$1/; $optparas =~ s/\s*(.*?)\s*/$1/; my @mandpara = map { [ split /\b/, $_ ] } split /\s*,\s*|\s+/, $mandparas; my @optpara = map { [ split /\b/, $_ ] } split /\s*,\s*|\s+/, $optparas; my $proto = join '', ( map { $_->[0] } @mandpara ), ';', map { $_->[0] } @optpara; my $vars = join ', ', map { ( length( $_->[0] ) == 2 ? '$' : $_->[0] ) . $_->[1] } @mandpara, @optpara; "sub $subnm($proto) { my ($vars) = \@_; " #egxs; } &trans; # translate and print print;