You wrote:

Thus what I'd want would rather be a set of especially named methods such as

sub AS_ARRAY { my $self=shift; # do something useful here }
so that
$obj->[42]; # would be the same as $obj->AS_ARRAY(42); # and so on...
But... that's exactly what arrayref-overloading does. I believe you can base your matrix class entirely on that. You'd access a matrix object $m like this
@$m # entire matrix, your syntax: $m->() $m->[ 1] # second row, your syntax $m->( 1); $m->[ 1]->[ 0] # individual element, your syntax $m->( 1, 0);
The syntax is pure Perl. Your's is more compact and closer to conventional mathematical notation. In fact, I like it and will keep it in mind for future matrix work.

Later you say:

...which is based, obviously, on blessed subrefs and also takes an Inside-Out approach: the object does contain something, namely a reference to itself, which also builds a closure, but is still used only like an index for property access.

Boo! That spoils most of the inside-out fun. Your objects rely on their body being a coderef, never mind how you access properties. Your class is hybrid to begin with and can't easily accomodate (inheritance-wise) a foereign class.

And it's not necessary either. Subref overloading is powerful enough to make your objects act as if their body were a coderef without it actually being one.

I have re-worked your class to be a true inside-out class without changing its interface or, I believe, its behavior. You may still prefer the more perlish style direct array overloading gives you and rewrite it that way.

I have also simplified your overload instructions somewhat.
package Matrix; use strict; use warnings; use Scalar::Util qw/refaddr/; use Data::Dumper; use base 'Exporter'; our @EXPORT='matrix'; use overload ( '""' => 'stringify', '*' => 'mult', '*=' => 'multby', '**' => 'pow', '&{}' => '_code', ); sub matrix { Matrix->new(@_) } sub mkaoa { [[ @_[0,1] ], [ @_[2,3] ]] } { my %entry; my %code; sub entry : lvalue { my $id=refaddr shift; @_==0 ? $entry{$id} : @_==1 ? $entry{$id}[ $_[0] ] : $entry{$id}[ $_[0] ][ $_[1] ]; } sub _code : lvalue { $code{ refaddr shift} } sub DESTROY { my $id = refaddr shift; delete $entry{ $id}; delete $code{ $id}; } } sub new { my $class = shift; my $self = bless( \ my $o, $class); $self->init(@_); } sub init { my $obj=shift; $obj->_code = sub : lvalue { $obj->entry(@_); }; $obj->() = mkaoa @_; $obj; } sub stringify { my $m = shift; "[[@{ $m->( 0) }] [@{ $m->( 1) }]]"; } sub _mult { my ($s,$o)=@_; my $code = $s->_code; $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, $n) = @_; my $out = matrix 1,0,0,1; if ( $n < 6 ) { $out->multby( $self) for 1 .. $n } else { my $pow = matrix map @$_, @{ $self->() }; # clone $self while ( $n ) { $out->multby( $pow) if $n & 1; $pow->multby( $pow); $n = int $n/2; } } $out; } 1; __END__
Anno

Update: Replaced the Matrix code. Essential change: ->init now does a full initialization instead of leaving part of the job to ->new. Inessential: Replaced ->pow with a more efficient implementation. Also added a stringification method


In reply to Re: Agile syntax (abuse?) by Anno
in thread Agile syntax (abuse?) by blazar

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.