2014-07-02 119 views
2

我正在玩弄Perl並創建一個字符串對象。我知道這是非常不好的想法在現實世界中做。我純粹是爲了好玩。你如何覆蓋替代操作?

我使用overload過載標準Perl 字符串運算符與標準運算符,你會發現在大多數其他語言。

use strict; 
use warnings; 
use feature qw(say); 

my $obj_string1 = Object::String->new("foo"); 
my $obj_string2 = Object::String->new("bar"); 
my $reg_string1 = "foobar"; 
my $reg_string2 = "barfu"; 

# Object::String "stringifies" correctly inside quotes 

say "$obj_string1 $obj_string2"; 

# Use "+" for concatenations 

say $obj_string1 + $obj_string2;    # Works 
say $obj_string1 + $reg_string1 + $reg_string2 # Works 

say $reg_string1 + $obj_string1     # Still works! 
say $reg_string1 + $obj_string1 + $reg_string2; # Still works! 
say $reg_string1 + $reg_string2 + $obj_string1; # Does't work, of course. 

# Overload math booleans with their string boolean equivalents 

my $forty = Object::String(40); 
my $one_hundred = "100"; 

if ($forty > $one_hundred) { # Valid 
    say "$forty is bigger than $one_hundred (in strings!)"; 
} 

if ($one_hundred < $forty) { # Also Valid 
    say "$one_hundred is less than $forty (In strings!)"; 
} 

# Some standard "string" methods 

say $forty->length  # Prints 5 
say $forty->reverse; # Prints "ytrof" 
say $forty;    # Prints "ytrof" 

現在到了最困難的部分:

my $string = Object::String("I am the best programmer around!"); 
say $string;    # Prints "I am the best programmer around" 
say $string->get_value; # Prints "I am the best programmer around" with get_value Method 

# But, it's time to speak the truth... 

$string =~ s/best programer/biggest liar/; 
say $string;    # Prints "I am the biggest liar around" 
say $string->get_value; # Whoops, no get_value method on scalar strings 

正如你所看到的,當我做我的替換,它工作正常,但返回普通的標量字符串,而不是一個對象:: string的。

我想弄清楚如何覆蓋替代操作。我查看了Perldoc,並且已經閱讀了各種Perl書籍(Advance Perl編程,中級Perl編程,Perl Cookbook等),但還沒有找到覆蓋替換操作的方法,因此它返回Object::String

如何覆蓋替代操作?

回答

4

不幸的是,Perl的超載支持在字符串領域並不是很普遍。有很多操作是超載不參加的;而s///就是其中之一。

我已經開始了一個模塊來解決這個問題; overload::substr但尚未完成。它允許您爲對象過載substr()函數,但到目前爲止它還沒有能力適用於m//s///

但是,您可能會在對象上使用左值(或4參數)substr()作爲欺騙的方法;如果對象至少被串化爲可以匹配的常規字符串,則可以使用substr() -rewrite技巧來完成替換。

打開

$string =~ s/pattern/replacement/; 

$string =~ m/pattern/ and substr($string, $-[0], $+[0]-$-[0]) = "replacement"; 

,然後你就會有一些代碼,會尊重一個substr()過載$string對象上,如果你用我上面的模塊。

當然在某些情況下,如果overload::substr可以執行它本身就會很好;我只是還沒有寫下來呢。

+0

'substr($ string,0)=〜s/pattern/replacement /;'是否有訣竅? – tobyink

+0

呵呵,我可以做大多數語言所做的,並且有'$ string_obj-> sub($ regex,$ repl,$ flags)'方法來執行類似'$ string =〜s/$ regex/$ repl/$ flags'。 –

+0

我的計劃是創建Object :: String,Object :: Number,Object :: Integer,Object :: Array等,幷包含複製基本Perl命令的方法。你在程序中使用Objectification;在Perl中以一種完全面向對象的風格寫入。所有類都使用'croak',所以Perl也變成了基於異常的類。你彈出一個沒有成員的列表或數組,並且你的程序崩潰。當然,學習Python會更容易,但我不想讓Guido van Rossum滿意。 –