Redefining a Function

Problem

You want to temporarily or permanently redefine a function, but functions can’t be assigned to.

Solution

To redefine a function, assign a new code reference to the typeglob of the name of the function. Use a local if you want it to be temporary.

undef &grow;                    # silence -w complaints of redefinition
*grow = \&expand;           
grow();                         # calls expand()

{
    local *grow = \&shrink;     # only until this block exists
    grow();                     # calls shrink()
}

Discussion

Unlike a variable but like a handle, a function cannot be directly assigned to. It’s just a name. You can manipulate it almost as though it were a variable, because you can directly manipulate the run-time symbol table using typeglobs like *foo to produce interesting aliasing effects.

Assigning a reference to a typeglob changes what is accessed the next time a symbol of that type is needed. This is what the Exporter does when you import a function or variable from one package into another. Since this is direct manipulation of the package symbol table, it only works on package variables (globals), not lexicals.

*one::var = \%two::Table;   # make %one::var alias for %two::Table
*one::big = \&two::small;   # make &one::big alias for &two::small

A typeglob is something you can use local on, but not my. Because of the local, this aliasing effect is then limited to the duration of the current block.

local *fred = \&barney;     # temporarily alias &fred to &barney

If the value assigned to a typeglob is not a reference but itself another typeglob, ...

Get Perl Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.