I have a lot of legacy code which shells out a lot, what i want to do is add a require
or minimal code changes to make the backticks do something different, for instance print instead of running code
i tried using use subs
but i couldn't get it to take over backticks or qx (i did redefine system which is one less thing to worry about)
i also tried to make a package:
package thingmbob;
use Data::Dumper;
use overload '``' => sub { CORE::print "things!:\t", Dumper \@_};
#this works for some reason
$thingmbob::{'(``'}('ls');
#this does the standard backtick operation
`ls`
unfourtunatly, I have no experience in OOP perl and my google-fu skills are failing me, could some one point me in the right direction?
caveat: I'm in a closed system with a few cpan modules preinstalled, odds are that i don't have any fancy modules preinstalled and i absolutely cannot get new ones
I'm on perl5.14
edit:
for the sake of completeness i want to add my (mostly) final product
BEGIN {
*CORE::GLOBAL::readpipe = sub {
print Dumper(\@_);
@internal = readpipe(@_);
if(wantarray){
return @internal;
}else{
return join('',@internal);
}
};
}
I want it to print what its about to run and then run it. the wantarray
is important because without it scalar context does not work
This perlmonks article explains how to do it. You can overwrite the readpipe
built-in.
EXPR is executed as a system command. The collected standard output of the command is returned. In scalar context, it comes back as a single (potentially multi-line) string. In list context, returns a list of lines (however you've defined lines with
$/
(or$INPUT_RECORD_SEPARATOR
inEnglish
)). This is the internal function implementing theqx/EXPR/
operator, but you can use it directly. Theqx/EXPR/
operator is discussed in more detail in I/O Operators in perlop. If EXPR is omitted, uses$_
.
You need to put this into a BEGIN
block, so it would make sense to not require
, but use
it instead to make it available as early as possible.
Built-ins are overridden using the CORE::GLOBAL::
namespace.
BEGIN {
*CORE::GLOBAL::readpipe = sub {
print "@_";
}
}
print qx/ls/;
print `ls`;
This outputs:
ls1ls1
Where the ls
is the @_
and the 1
is the return value of print
inside the overridden sub.
Alternatively, there is ex::override, which does the same under the hood, but with less weird internals.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With