你如何覆盖替代操作?

时间:2014-07-02 18:36:34

标签: perl operator-overloading override

我正在玩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

正如您所看到的,当我进行替换时,它可以正常工作,但会返回一个常规的标量字符串而不是Object :: String。

我试图找出如何覆盖替换操作。我查看过Perldoc,我已经阅读了各种Perl书籍(高级Perl编程,中级Perl编程,Perl Cookbook等),但还没有找到一种方法来覆盖替换操作,所以它返回一个Object::String

如何覆盖替换操作?

1 个答案:

答案 0 :(得分:4)

不幸的是,Perl的超载支持在字符串领域并不普遍。有很多操作,超载不是聚会的; s///就是其中之一。

我已经启动了一个模块来解决这个问题; overload::substr但目前还不完整。它允许您重置对象的substr()函数,但到目前为止,它还没有权力应用于m//s///

但是,您可以在对象上使用左值(或4参数)substr()作为欺骗这个的方法;如果对象至少串联成可以匹配的常规字符串,则可以使用substr() - 重写技巧完成替换。

打开

$string =~ s/pattern/replacement/;

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

然后,如果您使用上面的模块,那么您将拥有一些尊重substr()对象$string重载的代码。

在某些时候,如果overload::substr可以自己执行,那将会很好;我还没准备好写它。