ООП

[ Perl ]

26 Jun 2012

ООП в Perl

Сделаем класс треугольник.

1. Triangle.pm

package Triangle;
use strict;
use overload ('==' => \&equal,
 '""' => \&tostr);
sub new{
my $cl=shift; $cl = ref($cl)||$cl;
my @val= sort {$a <=> $b} @_;
print \@val,"\n";
return bless \@val,$cl;
}
sub P{
my $self=shift;
return $self->[0]
 +
 $self->[1]
 +
 $self->[2];}
sub equal{
my $self = shift;
my $other = shift;
return 0+(
 $self->[0] == $other->[0]
 && $self->[1] == $other->[1]
 && $self->[2] == $other->[2]);
}
sub tostr{
my $self = shift;
return ("<".$self->[0].", ".$self->[1].", ".$self->[2].">");
}
1;

 

2. STriangle.pm

package STriangle;
use strict;
require Triangle;
our @ISA=qw(Triangle);
sub S{
my $me=shift;
my $p2=0.5*$me->P();
return sqrt($p2*($p2-$me->[0])*($p2-$me->[1])*($p2-$me->[2]));
}
1;

 

3. main.pl

#!/usr/bin/perl -w
 $\=$/;
use STriangle;
 $tr_o = new STriangle(5,4,3);
print "$tr_o";
print "@$tr_o\n";
print "p= ",$tr_o->P()," S= ",$tr_o->S(),"\n";
 $tr_l = new STriangle(4,3,5);
print $tr_o->equal($tr_l);
print $tr_o==$tr_l;
print $tr_o->tostr();

Results

ARRAY(0x8d4ec80)
<3, 4, 5>
3 4 5
p= 12 S= 6
ARRAY(0x8d594f0)
1
1
<3, 4, 5>

Связывание

Класс Скаляр

Переопределение интересных встроенных методов.

Простейший пример

MyScalar.pm

package MyScalar;
my $cnt = 0;
sub TIESCALAR {
my $me;
return bless \$me, $_[0]; }
sub FETCH { ${$_[0]} }
sub STORE {
my ($me, $v) = @_;
 ++$cnt if $v<0;
 $$me=$v;
}
sub cnt {return $cnt;}
1;

Основная программа

#!/usr/bin/perl -w
use MyScalar;
 $a_a = tie $a, 'MyScalar';
for (1, 12.5, -13, 81e-1, -1_0_0) {$a=$_;}
print "'-'-->a = ",$a_a->cnt(), "\n";

Модифицированный

MyScalar1.pm

package MyScalar1;
sub TIESCALAR {
my %me={ val => undef, cnt => 0};
print 'TIESCALAR:',\$me,"\n";
return bless \%me, $_[0]; }
sub FETCH { $_[0]->{val} }
sub STORE {
my ($me, $v) = @_;
 ++($me->{cnt}) if $v<0;
 $me->{val}=$v;
}
sub cnt {return $_[0]->{cnt};}
1;

 

Тест для мода

#!/usr/bin/perl -w
use MyScalar1;
 $a_a = tie $a, 'MyScalar1';
 $b_b = tie $b, 'MyScalar1';
print '$a_a'."$a_a\n";
for (1, 12.5, -13, 81e-1, -1_0_0) {$a=$_; $b=-$_;}
print "'-'-->a = ",$a_a->cnt(), "\n";

С помощью списка

Готовая реализация

MyScalar3.pm

package MyScalar3;
my %cnts ;
use Tie::Scalar;
 @ISA = qw(Tie::StdScalar);
sub STORE {
my ($me, $v) = @_;
 $cnts{$me}++ if $v<0;
 $$me=$v;
}
sub cnt {return $cnts{$_[0]};}
sub DESTROY{
delete $cnts{$_[0]};}
1;

 

Основная программа

 #!/usr/bin/perl -w
use MyScalar;
 $a_a = tie $a, 'MyScalar';
 $b_b = tie $b, 'MyScalar';
for (1, 12.5, -13, 81e-1, -1_0_0) {$a=$_; $b=-$_;}
print "'-'-->a = ",$a_a->cnt(), "\n";