你如何覆盖替换操作?

Dav*_* W. 3 perl overriding operator-overloading

我在玩 Perl 并创建一个字符串对象。我知道在现实世界中这是一个非常糟糕的主意。我这样做纯粹是为了好玩。

我正在使用重载来重载标准 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"
Run Code Online (Sandbox Code Playgroud)

现在是困难的部分:

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
Run Code Online (Sandbox Code Playgroud)

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

我想弄清楚如何覆盖替换操作。我查看了 Perldoc,并阅读了各种 Perl 书籍(Advance Perl Programming、Intermediate Perl Programming、Perl Cookbook 等),但还没有找到覆盖替换操作的方法,因此它返回一个Object::String.

如何覆盖替换操作?

Leo*_*erd 5

不幸的是,Perl 的重载支持在字符串领域并不是很普遍。有许多操作与重载无关;并且s///是其中之一。

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

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

转动

$string =~ s/pattern/replacement/;
Run Code Online (Sandbox Code Playgroud)

进入

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

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

当然,在某些时候,如果overload::substr可以自己执行那会很好;我只是还没来得及写它。