NAME
Sub::HandlesVia::Manual::WithGeneric - 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.)
BUGS
Please report any bugs to https://github.com/tobyink/p5-sub-handlesvia/issues.
SEE ALSO
Misc advanced documentation: Sub::HandlesVia::Manual::Advanced.
Documentation for delegatable methods: Sub::HandlesVia::HandlerLibrary::Array, Sub::HandlesVia::HandlerLibrary::Blessed, Sub::HandlesVia::HandlerLibrary::Bool, Sub::HandlesVia::HandlerLibrary::Code, Sub::HandlesVia::HandlerLibrary::Counter, Sub::HandlesVia::HandlerLibrary::Enum, Sub::HandlesVia::HandlerLibrary::Hash, Sub::HandlesVia::HandlerLibrary::Number, Sub::HandlesVia::HandlerLibrary::Scalar, and Sub::HandlesVia::HandlerLibrary::String.
AUTHOR
Toby Inkster <tobyink@cpan.org>.
COPYRIGHT AND LICENCE
This software is copyright (c) 2022 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
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.