我想简单地覆盖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