Wrapped Subroutines
Sometimes you
might
want to wrap extra functionality around a subroutine that was already
defined (perhaps in a standard module), but still call it with the
same name. The .wrap
method is similar to the
.assuming method, but more powerful. It takes a
subroutine reference as an argument and returns an ID object. Inside
the subref wrapper, the call statement marks the
point where the original subroutine will be executed.
$id = &subname.wrap ({
# preprocess arguments
# or execute additional code
call;
# postprocess return value
# or execute additional code
})
subname( . . . ); # call the wrapped subroutineBy default, the inner subroutine is passed the same arguments as the
wrapping subroutine, and the wrapping subroutine returns the same
result as the inner subroutine. You can alter the arguments passed to
the inner subroutine by adding an explicit argument list to
call, and alter the outer return value by
capturing the result from call and explicitly
returning a value in the wrapper.
$id = &subname.wrap (sub (*@args) {
# preprocess arguments
$result = call('modified', 'arguments');
# postprocess return value
return $result;
})A subroutine can have multiple wrappers at the same time. Each new
wrapper wraps around the previous one, and the outermost wrapper
executes first. The ID object returned by .wrap
allows the .unwrap method to remove a specific
wrapper:
&subname.unwrap($id);
If you’d rather not manually unwrap your sub, wrap a
temped version instead. The ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access