Sub::HandlesVia::Manual::WithGeneric(3pm)

Sub::HandlesVia::Manual::WithGeneric3pm

Using sub::handlesvia with generic perl classes

Manual

Sub::HandlesVia allows you to delegate methods from your class to the values of your objects' attributes.

Conceptually, it allows you to define "$object->push_number($n)" to be a shortcut for "$object->numbers->push($n)" except that "$object->numbers" is an arrayref, so doesn't have methods you can call on it like "push".

For Moose and Mouse, Sub::HandlesVia can use their metaobject protocols to grab an attribute's definition and install the methods it needs to. For Moo, it can wrap "has" and do its stuff that way. For other classes, you need to be more explicit and tell it what methods to delegate to what attributes.

 package Kitchen {
   
   # constructor
   sub new {
     my ( $class, %arg ) = @_;
     $arg{food} ||= [];
     return bless( \%arg, $class );
   }
   
   # getter/setter for `food`
   sub food {
     (@_ == 1) ? $_[0]{food} : ( $_[0]{food} = $_[1] );
   }
   
   use Sub::HandlesVia qw( delegations );
   
   delegations(
     attribute   => 'food'
     handles_via => 'Array',
     handles     => {
       'add_food'    => 'push',
       'find_food'   => 'grep',
     },
   );
 }

Setting "attribute" to "food" means that when Sub::HandlesVia needs to get the food list, it will call "$kitchen->food" and when it needs to set the food list, it will call "$kitchen->food($value)". If you have separate getter and setter methods, just do:

     attribute   => [ 'get_food', 'set_food' ],

Or if you don't have any accessors and want Sub::HandlesVia to directly access the underlying hashref:

     attribute   => '{food}',

Or maybe you have a setter, but want to use hashref access for the getter:

     attribute   => [ '{food}', 'set_food' ],

Or maybe you still want direct access for the getter, but your object is a blessed arrayref instead of a blessed hashref:

     attribute   => [ '[7]', 'set_food' ],

Or maybe your needs are crazy unique:

     attribute   => [ \&getter, \&setter ],

The coderefs are passed the instance as their first argument, and the setter is also passed a value to set.

Really, I don't think there's any object system that this won't work for!

If you supply an arrayref with a getter and setter, it's also possible to supply a third argument which is a coderef or string which will be called as a method if needing to "reset" the value. This can be thought of like a default or builder.

(The "delegations" function can be imported into Moo/Mouse/Moose classes too, in which case the "attribute" needs to be the same attribute name you passed to "has". You cannot use a arrayref, coderef, hash key, or array index.)

Disclaimer of warranties

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

Releases

3 releases since Debian 12 (Bookworm); the text changed 2 times.

  1. 12
  2. 13
  3. Arch

Bugs

Please report any bugs to <https://github.com/tobyink/p5-sub-handlesvia/issues>.

Author

Toby Inkster <[email protected]>.

From perl-sub-handlesvia 0.053005-1 in Arch Linux 2026-11-01. Parsed by carta from the page's man source.