ООП в 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";