=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 fo
+r 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;
|