我想简单地覆盖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使用本地声明呢?
当然,另一种解决方案是使用length
将每次调用重命名为ansi_length
并相应地重命名自定义函数。
对于那些想要更多细节的人:
我想覆盖核心模块length
的上下文是一个生成ASCII表的简短代码(有点像Text::ASCIITable
,但具有不同的功能,如多列和多行)。我不想编写一个专用的Perl模块,因为我希望尽可能保持我的程序是单片的,因为使用它的人不熟悉CPAN甚至模块安装。
在此代码中,我需要知道每行中每列的宽度,以便正确对齐它们。当单元格包含带有^[[33mgreen^[[0m
等ANSI序列的彩色文本时,我需要忽略着色序列。
由于我已在程序中使用UTF-8字符,因此我必须将其添加到我的程序中:
use utf8;
use open ':std', ':encoding(UTF-8)';
我注意到utf8
模块也会重载核心子例程length
。我意识到这对我来说也是一个很好的解决方案。
最后我想我在这个问题上添加了足够的细节。我很高兴得到通知,为什么我对这个问题有所了解。我不认为我能说得更清楚。此外,我认为所有这些细节都无法理解最初的问题......
答案 0 :(得分:7)
覆盖核心功能不是一个好主意。如果您使用库,那么它本身使用核心函数,库函数将面临覆盖函数并可能失败。你可以创建一个自己的模块/命名空间ANSI ::或者..然后使用ANSI :: length,但我认为使用你提出的名称是更好的:ansi_length。
如果你还坚持: 您可以使用
覆盖核心功能BEGIN {
*CORE::GLOBAL::length = sub ...
}
每当您需要访问原始CORE功能时,请使用 CORE ::长度。
这适用于Perl的所有内置函数。