sub AS_ARRAY {
my $self=shift;
# do something useful here
}
####
$obj->[42]; # would be the same as
$obj->AS_ARRAY(42); # and so on...
####
# -*- Perl -*-
use strict;
use warnings;
package Matrix;
use Scalar::Util qw/refaddr/;
use Data::Dumper;
use base 'Exporter';
our @EXPORT='matrix';
use overload
'*' => sub { $_[0]->mult($_[1]) },
'*=' => sub { $_[0]->multby($_[1]) },
'**' => sub { $_[0]->pow($_[1]) };
sub matrix { Matrix->new(@_) }
sub mkaoa { [[ @_[0,1] ], [ @_[2,3] ]] }
{
my %entry;
sub entry : lvalue {
my $id=refaddr shift;
@_==0 ? $entry{$id} :
@_==1 ? $entry{$id}[ $_[0] ] :
$entry{$id}[ $_[0] ][ $_[1] ];
}
sub DESTROY { delete $entry{refaddr shift} }
}
sub new {
my $class = shift;
my $self;
$self = sub : lvalue { $self->entry(@_) };
bless($self => $class)->init(@_);
}
sub init {
my $obj=shift;
$obj->() = mkaoa @_;
$obj;
}
sub _mult {
my ($s,$o)=@_;
$s->(0,0)*$o->(0,0) + $s->(0,1)*$o->(1,0),
$s->(0,0)*$o->(0,1) + $s->(0,1)*$o->(1,1),
$s->(1,0)*$o->(0,0) + $s->(1,1)*$o->(1,0),
$s->(1,0)*$o->(0,1) + $s->(1,1)*$o->(1,1);
}
sub mult {
my ($s,$o)=@_;
matrix $s->_mult($o)
}
sub multby {
my ($s,$o)=@_;
$s->() = mkaoa $s->_mult($o);
$s;
}
sub pow {
my ($self, $pow)=@_;
my $out=matrix 1,0,0,1;
$out->multby($self) for 1..$pow;
$out;
}
1;
__END__
####
#!/usr/bin/perl -l
use strict;
use warnings;
use Matrix;
# A somewhat esoteric way to print the
# twelfth Fibonacci number.
print +(matrix(1,1,1,0)**12)->(1,0);
__END__
####
#!/usr/bin/perl
use strict;
use warnings;
package Foo;
use Scalar::Util qw/refaddr/;
{
my %bar;
sub bar {
my $id=refaddr shift;
@_ ? $bar{$id}=shift : $bar{$id};
}
sub DESTROY {
my $obj=shift;
warn "Deleting $obj\n";
delete $bar{refaddr $obj};
}
}
sub new {
my ($class, $type, $data)=@_;
my $obj;
$obj=bless $type eq 'code' ?
sub { $obj } :
{} => $class;
warn "Creating $obj\n";
$obj->bar($data);
}
package main;
sub test {
my $type=shift;
warn "--- Testing <$type> ---\n";
my $x=Foo->new($type => 'x');
warn "Leaving context\n";
}
test $_ for qw/code other/;
END { warn "Leaving program\n" }
__END__
####
--- Testing ---
Creating Foo=CODE(0x224eb4)
Leaving context
--- Testing ---
Creating Foo=HASH(0x225bec)
Deleting Foo=HASH(0x225bec)
Leaving context
Leaving program
Deleting Foo=CODE(0x224eb4)