如何在Perl中覆盖子例程,例如' length '



我想简单地覆盖length子程序,以考虑到ANSI转义序列,所以我这样写:

sub length {
    my $str = shift;
    if ($cfg{color}) {
        return length($str =~ s/x1B[d+[^m]*m//gr);
    } 
    return length($str);
}

不幸的是,Perl检测到有歧义的调用被替换为CORE::length

我怎么能告诉Perl使用本地声明代替?

当然,另一种解决方案是用ansi_length重命名每个对length的调用,并相应地重命名自定义函数。

想了解更多细节:

我想覆盖核心模块length的上下文是生成ASCII表的短代码(有点像Text::ASCIITable,但具有不同的功能,如多列和多行)。我不想编写一个专门的Perl模块,因为我想让我的程序尽可能保持单一,因为使用它的人不熟悉CPAN,甚至不熟悉模块安装。

在这段代码中,我需要知道每一行中每列的宽度,以便正确对齐它们。当单元格包含带有ANSI序列(如^[[33mgreen^[[0m)的有色文本时,我需要忽略着色序列。

因为我已经在我的程序中使用了UTF-8字符,所以我必须把这个添加到我的程序中:

use utf8;
use open ':std', ':encoding(UTF-8)';

我注意到utf8模块也重载了核心子程序length。我意识到这对我来说也是一个很好的解决方案。

最后,我想我给这个问题添加了足够多的细节。我很高兴被告知为什么我在这个问题上得到了否定。我想我不能说得更清楚了。此外,我认为所有这些细节对理解最初的问题根本没用。

覆盖核心函数不是一个好主意。如果使用本身使用核心函数的库,则库函数将面临被覆盖的函数并可能失败。你可以创建一个自己的模块/命名空间ANSI::左右,然后使用ANSI::length,但我认为最好使用你建议的名称:ansi_length。

如果你仍然坚持:您可以使用

覆盖核心函数
BEGIN {
  *CORE::GLOBAL::length = sub ... 
}

当您需要访问原始CORE函数时,使用核心:长度。

这对Perl的所有内置函数都有效。

这里是一个参考:http://perldoc.perl.org/CORE.html

最新更新