Perl中左值子例程的用途是什么?

Perl中左值子例程的用途是什么?,perl,subroutine,lvalue,Perl,Subroutine,Lvalue,我不明白左值子程序的用途是什么?有什么是我不能用常规子程序完成的?你能举一些例子吗 谢谢它们提供了一个不同的界面,在某些情况下可以更加直观。与传统的setter不同,您实际上可以直接更改值。比如说 lvalue_sub($foo) =~ s/foo/bar/; 可以比 my $tmp = some_sub($foo); $tmp =~ s/foo/bar/; some_sub($foo, $tmp); 建议避免使用左值。它们很有趣,但它们会让那些对所有sub的工作方式做出假设的新用户感到困惑

我不明白左值子程序的用途是什么?有什么是我不能用常规子程序完成的?你能举一些例子吗


谢谢它们提供了一个不同的界面,在某些情况下可以更加直观。与传统的setter不同,您实际上可以直接更改值。比如说

lvalue_sub($foo) =~ s/foo/bar/;
可以比

my $tmp = some_sub($foo);
$tmp =~ s/foo/bar/;
some_sub($foo, $tmp);

建议避免使用左值。它们很有趣,但它们会让那些对所有sub的工作方式做出假设的新用户感到困惑,因此当有更好的方法可用时,应该在代码中避免使用

有时,使用左值结果做脏活是非常实际的

substr( $string, $start, $stop ) = 'somevalue' # replaces the specified part of the substring. 
然而,这也做了同样的事情:

substr( $string, $start, $stop , 'somevalue' ); 
这里的区别主要是前者具有更大的表达能力,因为它将行为委托给使用它的代码,而不是函数本身

例如:

substr( $string, $start, $stop ) =~ s/a/b/g 
需要你做什么

my $x = substr( $string, $start, $stop ); 
$x =~ s/a/b/g/; 
substr( $string, $start, $stop, $x );
这有点恶心


尽管如此,这里还有一个额外的问题,因为您必须考虑使用$x进行替换是否可以追溯到修改字符串(因为substr是一个左值sub)。我不认为它有,但它不够明确,我必须检查手册以记住它是否有,这很糟糕

您可以使用左值子对象作为对象成员的设置器:

sub x : lvalue {
    my $self = shift;
    $self->{x};
}
随后:

$foo->x = 5;
这将直接设置成员的直观性与封装setter的灵活性结合起来,以防以后需要更改对象的实现方式。与以下更传统的Perl成员设置方法相比:

直觉但脆弱;如果更改$foo的实现方式会怎么样

$foo->{x} = 5;
传统的setter方法;对于相当于赋值的内容,不使用赋值语法:

$foo->set_x(5);

当然,左值方法从来没有真正被Perl社区所接受,左值子类的使用是“奇怪的”,任何能从直觉中获得的东西都会因为它的奇怪而丢失。

我不能说在我的普通Perl东西中使用了太多左值子类,但是,在Perl数据语言中,在获取片段或其他片段时,它们被广泛使用。例如:

my $a = sequence(100);
# use lvalue in this increment:
$a->where($a < 10)++;

# Zero-out the last four elements
# notice the use of the overloaded .= operator:
$a->slice("-10:") .= 0;
my$a=序列(100);
#在此增量中使用左值:
$a->where($a<10)+;
#将最后四个元素归零
#请注意重载的。=运算符的用法:
$a->slice(“-10:”)。=0;

与Perl中的许多功能一样,这个功能在整个生态系统中使用得不多,但它的使用至少使PDL用户的生活更加轻松。

$x包含一个副本,而不是左值。但是如果你将左值substr ala
别名为(substr(…){
foo(substr(…)
你可以用左值做不止一件事。我在理解你的一些短语时遇到了困难:A)“使用左值结果做肮脏的工作。”但我看不到示例中所示的内容,或者我不明白你的意思“一个左值结果”B“,因为它将行为委托给使用它的代码,而不是函数本身。“也许这是关于非母语英语,但我对这里的代词和C的含义感到困惑”,因为您必须考虑使用$x进行替换是否可以追溯修改字符串"对我来说太不清楚了,甚至不能指出如何正确……注意,就像状态一样,使用LVC++子这样的设置排除了验证输入的可能性。换句话说,使用LValus子作为访问器的功能比普通方法更为强大。对于结构成员。但是没有人将此引用为“struct”的问题。