2015-05-23 24 views
1

我想簡單地覆蓋length子程序採取帳戶ANSI轉義序列,所以我寫了這個:如何在Perl中覆蓋諸如`length`的子程序?

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

不幸的是Perl的檢測是remplaced與CORE::length曖昧電話。

我該如何告訴Perl使用本地聲明呢?

當然,另一種解決方案是將每個呼叫重命名爲lengthansi_length並相應地重命名自定義功能。

,誰想要更多的細節:

,我想重寫核心模塊length上下文是產生ASCII表短代碼(有點像Text::ASCIITable,但具有不同的功能,如multicolumns和multirows) 。我不想寫一個專門的Perl模塊,因爲我想盡可能保持我的程序儘量單一,因爲使用它的人不熟悉CPAN甚至模塊安裝。

在這段代碼中,我需要知道每行中每列的寬度,以便正確對齊它們。當單元格包含帶有ANSI序列(如^[[33mgreen^[[0m)的彩色文本時,我需要忽略着色序列。

正如我已經在我的程序中使用UTF-8字符,我不得不把它添加到我的計劃:

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

我注意到utf8模塊還超載核心子程序length。我意識到這對我來說也是一個很好的解決方案。

最終我想我在這個問題中增加了足夠的細節。我很高興得到通知,爲什麼我在這個問題上得到了低估。我認爲我不能說得更清楚。此外,我認爲所有這些細節都不是有用的瞭解最初的問題...

回答

7

覆蓋核心功能不是一個好主意。如果你使用一個庫,它本身使用核心函數,庫函數將面臨被覆蓋的函數並可能失敗。你可以創建一個自己的模塊/命名空間ANSI ::或者...然後使用ANSI :: length,但是我認爲使用像你所建議的名稱是不好的:ansi_length。

如果你還是堅持: 您可以

BEGIN { 
    *CORE::GLOBAL::length = sub ... 
} 

覆蓋核心功能每當你需要訪問源核功能,使用 CORE ::長度。

這對Perl中的所有函數都有效。

這裏是一個參考:http://perldoc.perl.org/CORE.html

+0

的'utf8'模塊過載'length'子程序。我明白'utf8'也是一個核心模塊,但我不完全明白這是什麼不同。 – nowox

+0

「utf8」是特別的東西。所謂的「雜注」或更好的「特徵」。你可以在腳本的開頭寫上「use utf8;」來告訴perl文本使用utf-8編碼。 –

+1

utf8誘發的重載僅在使用編譯指示的腳本中可見。這與「嚴格使用」是一樣的。它的範圍是寫入它的腳本。 –