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 subroutine By 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 temp ed version instead. The temp automatically removes the wrapper at the end of its scope. { temp &subname.wrap ({ . . . }) subname( . . . ); } |