【问题标题】:redefining or overloading backticks重新定义或重载反引号
【发布时间】:2017-03-08 11:28:31
【问题描述】:

我有很多遗留代码,我想要做的是添加一个require 或最小的代码更改以使反引号做一些不同的事情,例如打印而不是运行代码

我尝试使用use subs,但我无法让它接管反引号或 qx(我确实重新定义了系统,这是一件少担心的事情)

我也尝试过打包:

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`

不幸的是,我没有 OOP perl 方面的经验,而且我的 google-fu 技能也让我失望,有人能指出我正确的方向吗?

警告: 我在一个预装了一些 cpan 模块的封闭系统中,很可能我没有预装任何花哨的模块,而且我绝对无法获得新的模块

我在 perl5.14

编辑:

为了完整起见,我想添加我的(大部分)最终产品

BEGIN {
    *CORE::GLOBAL::readpipe = sub {
        print Dumper(\@_);
        @internal = readpipe(@_);
        if(wantarray){
            return @internal;
        }else{
            return join('',@internal);
        }
    };
}

我希望它打印出即将运行的内容,然后运行它。 wantarray 很重要,因为没有它标量上下文不起作用

【问题讨论】:

  • overload 帮不了你。那是在特定上下文中使用具有重载的当前对象时,例如 DateTime->now + 5 会神奇地工作。
  • 看来qx 不能被覆盖。见this answer。 (我不是说你不能以某种方式完成你想要的:)

标签: perl


【解决方案1】:

perlmonks article 解释了如何做到这一点。您可以覆盖 readpipe 内置。

EXPR 作为系统命令执行。返回收集到的命令标准输出。在标量上下文中,它以单个(可能是多行)字符串的形式返回。在列表上下文中,返回行列表(但是您已经使用$/(或English 中的$INPUT_RECORD_SEPARATOR)定义了行)。这是实现qx/EXPR/ 运算符的内部函数,但您可以直接使用它。 qx/EXPR/ 运算符在 perlop 中的 I/O 运算符中有更详细的讨论。如果省略 EXPR,则使用 $_

您需要将其放入 BEGIN 块中,因此最好不要使用 require,而是使用 use 以尽早使其可用。

使用CORE::GLOBAL:: namespace 覆盖内置插件。

BEGIN {
    *CORE::GLOBAL::readpipe = sub {
        print "@_";
    }
}

print qx/ls/;
print `ls`;

这个输出:

ls1ls1

其中ls@_1 是覆盖子内print 的返回值。

另外,还有ex::override,它在引擎盖下做同样的事情,但内部结构不那么奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多