tie @array, 'Tie::ArrayXYZ'; tied(@array)->method(@args); #### $obj = tie @array, 'Tie::ArrayXYZ'; $obj->method(@args); #### method(@array, @args); #### package Tie::ArrayXYZ; use Tie::Functions qw( @ changeXYZ ); # ... sub CHANGEXYZ { my ($obj, $new_xyz) = @_; $obj->{XYZ} = $new_xyz; } 1; #### use Tie::ArrayXYZ; tie @array, 'Tie::ArrayXYZ', $some_xyz; # ... tied(@array)->CHANGEXYZ($new_xyz); #### use Tie::ArrayXYZ; tie @array, 'Tie::ArrayXYZ', $some_xyz; # ... changeXYZ(@array,$new_xyz); #### sub main::changeXYZ (\@@) { my $arg = shift; my $obj = tied @$arg; Carp::croak( "First arg to main::changeXYZ must be array tied to Tie::ArrayXYZ" ) unless defined($obj) and $obj->isa("Tie::ArrayXYZ"); return $obj->CHANGEXYZ(@_); } #### use Tie::Functions VARTYPE, FUNCTIONS; #### package Tie::Functions; use Carp; my %trans = qw( $ scalar @ array % hash * glob ); sub import { shift; my $type = shift; my $pkg = caller(0); my $ppkg = caller(1); croak "Type must be '\$', '\@', '%', '*', not '$type'." unless $type eq '$' or $type eq '@' or $type eq '%' or $type eq '*'; eval qq[ sub ${ppkg}::$_ (\\$type\@) { my \$arg = shift; my \$obj = tied $type\$arg; Carp::croak( "First arg to ${ppkg}::$_ must be $trans{$type} tied to $pkg" ) unless defined(\$obj) and \$obj->isa("$pkg"); return \$obj->\U$_\E(\@_); } ] for @_; } 1;