Sub::Ha...ry::Code(3)

πŸ’– Sub::Ha...ry::Code β€” User Contributed Perl Documentation πŸ’–

okay bestie, buckle up, we're reading the manual for Sub::HandlesVia::HandlerLibrary::Code and honestly? it's giving delegation but make it coderef. πŸŽ€


✨ NAME ✨

Sub::HandlesVia::HandlerLibrary::Code β€” bestie it's a whole library of code-related methods πŸ¦‹


🌸 SYNOPSIS 🌸

here's the vibe, no cap:

package My::Class {
  use Moo;
  use Sub::HandlesVia;
  use Types::Standard 'CodeRef';
  has attr => (
    is => 'rwp',
    isa => CodeRef,
    handles_via => 'Code',
    handles => {
      'my_execute' => 'execute',
      'my_execute_list' => 'execute_list',
      'my_execute_method' => 'execute_method',
      'my_execute_method_list' => 'execute_method_list',
      'my_execute_method_scalar' => 'execute_method_scalar',
      'my_execute_method_void' => 'execute_method_void',
      'my_execute_scalar' => 'execute_scalar',
      'my_execute_void' => 'execute_void',
    },
  );
}

πŸ’… DESCRIPTION πŸ’…

so basically, this is a library of methods for Sub::HandlesVia. that's it, that's the whole thing. iconic. πŸ‘‘


🌈 DELEGATABLE METHODS 🌈

all the goodies. every single one. let's go 🫢

⭐ execute( @args )

calls the coderef, and passes it any arguments you hand over. simple as.

my $coderef = sub { 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( 1, 2, 3 )
$object->my_execute( 1, 2, 3 );

⭐ execute_list( @args )

calls the coderef, passes it any arguments, and forces list context. and if you call it in scalar context? it hands you back an arrayref. the way it just adapts 😭

my $context;
my $coderef = sub { $context = wantarray(); 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( 1, 2, 3 )
my $result = $object->my_execute_list( 1, 2, 3 );

say Dumper( $result );  ## ==> [ 'code' ]
say $context;           ## ==> true

⭐ execute_method( @args )

calls the coderef as if it were a method, passing any arguments. yes, it's methodifying your coderef. main character energy fr fr πŸ’…

my $coderef = sub { 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( $object, 1, 2, 3 )
$object->my_execute_method( 1, 2, 3 );

⭐ execute_method_list( @args )

calls the coderef as if it were a method, passing any arguments, and forcing list context. called in scalar context? arrayref, bestie. we been knew.

my $context;
my $coderef = sub { $context = wantarray(); 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( $object, 1, 2, 3 )
my $result = $object->my_execute_method_list( 1, 2, 3 );

say Dumper( $result );  ## ==> [ 'code' ]
say $context;           ## ==> true

⭐ execute_method_scalar( @args )

calls the coderef as if it were a method, passing any arguments, and forcing scalar context. no list vibes allowed here πŸ™ˆ

my $context;
my $coderef = sub { $context = wantarray(); 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( $object, 1, 2, 3 )
my $result = $object->my_execute_method_scalar( 1, 2, 3 );

say $result;  ## ==> 'code'
say $context; ## ==> false

⭐ execute_method_void( @args )

calls the coderef as if it were a method, passing any arguments, and forcing void context. returns undef. literally nothing comes back. it's giving ghosted πŸ’€

my $context;
my $coderef = sub { $context = wantarray(); 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( $object, 1, 2, 3 )
my $result = $object->my_execute_method_void( 1, 2, 3 );

say $result;  ## ==> undef
say $context; ## ==> undef

⭐ execute_scalar( @args )

calls the coderef, passes it any arguments, and forces scalar context. one value, one vibe.

my $context;
my $coderef = sub { $context = wantarray(); 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( 1, 2, 3 )
my $result = $object->my_execute_scalar( 1, 2, 3 );

say $result;  ## ==> 'code'
say $context; ## ==> false

⭐ execute_void( @args )

calls the coderef, passes it any arguments, and forces void context. returns undef. absolutely nothing returned, bestie, and that's the point ✨

my $context;
my $coderef = sub { $context = wantarray(); 'code' };
my $object  = My::Class->new( attr => $coderef );

# Calls: $coderef->( 1, 2, 3 )
my $result = $object->my_execute_void( 1, 2, 3 );

say $result;  ## ==> undef
say $context; ## ==> undef

πŸ¦‹ EXTENDED EXAMPLES πŸ¦‹

okay this is the part where it gets good. real talk.

πŸŽ€ Using execute_method

the execute_method handler lets a class effectively provide certain methods which can be overridden by parameters in the constructor. the way that works?? obsessed.

use strict;
use warnings;
use Data::Dumper;

package My::Processor {
  use Moo;
  use Sub::HandlesVia;
  use Types::Standard qw( Str CodeRef );

  has name => (
    is => 'ro',
    isa => Str,
    default => 'Main Process',
  );

  my $NULL_CODEREF = sub {};

  has _debug => (
    is => 'ro',
    isa => CodeRef,
    handles_via => 'Code',
    handles => { debug => 'execute_method' },
    default => sub { $NULL_CODEREF },
    init_arg => 'debug',
  );

  sub _do_stuff {
    my $self = shift;
    $self->debug( 'continuing process' );
    return;
  }

  sub run_process {
    my $self = shift;
    $self->debug( 'starting process' );
    $self->_do_stuff;
    $self->debug( 'ending process' );
  }
}

my $p1 = My::Processor->new( name => 'First Process' );
$p1->run_process; # no output

my @got;
my $p2 = My::Processor->new(
  name => 'Second Process',
  debug => sub {
    my ( $processor, $message ) = @_;
    push @got, sprintf( '%s: %s', $processor->name, $message );
  },
);
$p2->run_process; # logged output

my @expected = (
  'Second Process: starting process',
  'Second Process: continuing process',
  'Second Process: ending process',
);
say Dumper( \@got ); ## ==> \@expected

see how $p1 is silent because the default is $NULL_CODEREF, and $p2 passes its own debug coderef through the constructor? that's the whole flex. πŸ’…


πŸ’€ BUGS πŸ’€

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

not me asking you to file issues, but like. if you find one, spill. 🫢

πŸ‘‘ SEE ALSO πŸ‘‘

Sub::HandlesVia.


🌸 AUTHOR 🌸

Toby Inkster <tobyink@cpan.org>.


This software is copyright (c) 2020, 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.

bestie that's legalese for "no promises, it is what it is" 😭

and that's the whole page!! this one's from perl v5.42.0, dated 2026-02-11, and it's the Sub::Ha...ry::Code(3) manual under User Contributed Perl Documentation. slay, go delegate some coderefs, ily πŸ’œβœ¨πŸŽ€

πŸ“¦ where this page comes from