NAME

Sub::Define - Easily define and redefine variably named subroutines

SYNOPSIS

use Sub::Define qw/ define_sub /;

define_sub(foo => sub { print "I'm &foo!" });

my $old = define_sub('Bar::baz' => sub { print "I'm &Bar::baz!" });

my $pkg = 'Zap';
my $subname = 'zoop';
my $code = sub { print "I'm &$pkg\::$subname!" };
define_sub($pkg, $subname, $code);

foo();
Bar::baz();
Zap::zoop();

__END__
I'm &foo!
I'm &Bar::baz!
I'm &Zap::zoop!

DESCRIPTION

This module makes it easier for you to define and redefine subroutines with variable names and in variable packages.

In order to support alternative package/class definitions any class can override the default behaviour.

FUNCTIONS

my $old_code = define_sub($subname, $code);

The first argument is the name of the subroutine to define and is the subroutine reference which will become it's definition. If the subroutine name is unqualified the the current package will be used.

package Foo;
define_sub(foo => sub { ... };         # &Foo::foo
define_sub('Bar::foo' => sub { ... }); # &Bar::foo

This is just like doing

package Foo;
*foo = sub { ... };
*Bar::foo = sub { ... };

except you can use variables easily.

If &define_sub is called in scalar or list context then a reference to any subroutine already used for $subname is returned; otherwise a false value is returned. Calling &define_sub in scalar or list context has the additional effect of silencing any "Subroutine %s redefined" warning.

(Note that just as

package Foo;
*ARGV = sub { ... };

puts the &ARGV subroutine in the main package instead of in Foo, so does

package Foo;
define_sub(ARGV => sub { ... });

This applies to all symbols that resolve to the main package when used unqualified. Fully qualified names aren't effected by this, just as they aren't in subroutine definitions.)

Note that if the default behaviour is overridden by the target package it's completely up to the author of that package to decide what it should do and warn about.

my $old_code = define_sub($pkg, $subname, $code);

If a package name is supplied at the beginning of the argument list, &define_sub will treat it as if it was the current package.

package Foo;
define_sub('Zap', foo => sub { ... };         # &Zap::foo

The behaviour of

define_sub('Zap', 'Bar::foo' => sub { ... }); # &Bar::foo

i.e. when you have a package name and a fully qualified name is somewhat experimental.

OVERRIDING &define_sub

A package can override &define_sub by providing a &SUB_DEFINE_define_sub method and inheriting from Sub::Define::Interface. Sub::Define::Interface doesn't provide any functionality but is used to signal that &SUB_DEFINE_define_sub in the package indeed is intended to override the default behaviour &define_sub.

Example of overriding &define_sub

Let's say we have a class where all subroutines are stored in a hash called %subs. Thus, if you want to install a subroutine, you want to manipulate &subs instead of the symbol table.

package HashSubs;
use Sub::Define; # create Sub::Define::Interface
use base 'Sub::Define::Interface';

my %subs = (
    foo => sub { "I'm foo!" };
    bar => sub { "I'm bar!" };
);

sub SUB_DEFINE_define_sub {
    my ($pkg, $name, $code) = @_;

    my $old = $subs{$name};
    $subs{$name} = $code;

    return $old;
}

We can now, in any package, do

use Sub::Define qw/ define_sub /;

define_sub('HashSubs::baz' => sub { "I'm baz!" });

and the baz subroutine is correctly added.

EXAMPLES

All examples assume

use Sub::Define qw/ define_sub /;

Generating subroutines

for my $name (qw/ foo bar baz /) {
    define_sub(
        $name => sub {
            print "I'm $name!\n";
        }
    );
}

foo();
bar();
baz();

__END__
I'm foo!
I'm bar!
I'm baz!

Wrapping subroutines

sub foo { print "old foo\n" }

my $old;
$old = define_sub(
    foo => sub {
        $old->();
        print "new foo\n";
    }
);

foo();

__END__
old foo
new foo

AUTHOR

Johan Lodin <lodin@cpan.org>

COPYRIGHT

Copyright 2005 Johan Lodin. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

Sub::Name - give internal name to anonymous subroutines (useful for getting informative error messages).