package Vector { sub new{ my $class = shift; bless [ map{ int() == 0+$_ ? int() : die( "'$_' not an integer in Vector::new" ) } @_ ], $class } sub item :lvalue { $_[0]->[ $_[1] ] } 1; } package Matrix { sub new { my $class = shift; bless [ map{ ref() eq 'Vector' ? $_ : die "'$_' not a Vector in Matrix::new" } @_ ], $class } sub item :lvalue { $_[0]->[ $_[1] ]->item( $_[2] ); } sub mmMxN { use integer; my( $self, $other ) = @_; die "Incompatible matrix dimensions" unless @{ $self } == @{ $other->[0] }; my $return = Matrix->new( map Vector->new( (0) x @{ $self } ), 0 .. $#{ $other->[ 0 ] } ); for my $i ( 0 .. $#{ $self } ) { for my $j ( 0 .. $#{ $other->[0] } ) { $return->item( $i, $j ) += $self->item( $i, $_ ) * $other->item( $_, $j ) for 0 .. $#{ $other }; } } return $return; } 1; }