我不明白左边缘子程序的用途是什么?用普通子程序无法完成的是什么?你能发一些例子吗?
谢谢
您可以将lvalue subs用作对象成员的setter:
sub x : lvalue { my $self = shift; $self->{x}; }
然后呢:
$foo->x = 5;
这将直接设置成员的直观性与封装setter的灵活性结合在一起,以防您以后想要更改对象的实现方式.与以下更传统的方法在Perl中设置成员相比:
直觉但脆弱; 如果你改变$ foo的实现怎么办?
$foo->{x} = 5;
传统的二传手法; 不使用赋值语法来指定赋值:
$foo->set_x(5);
当然,lvalue方法从未真正被Perl社区所接受,并且lvalue subs的使用是"奇怪的",并且任何因直观性而获得的东西都会因为它的奇怪性而丢失.
建议避免使用LValues.它们很有趣,但它们让新用户感到困惑,他们对所有子设备的工作方式做出了假设,因此当有更好的方法时,应该避免使用代码.
有时,使用LValue结果进行肮脏的工作是非常实际的.
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是一个LValue子).我不认为它,但它含糊不清我必须检查手册,以记住它是否有,这是不好的.
它们提供了不同的界面,在某些情况下可以更直观.与传统的setter不同,您实际上可以直接更改值.例如
lvalue_sub($foo) =~ s/foo/bar/;
可以比清洁
my $tmp = some_sub($foo); $tmp =~ s/foo/bar/; some_sub($foo, $tmp);
我不能说我在普通的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;
像Perl中的许多东西一样,这个功能在整个生态系统中并没有被广泛使用,但它至少在这个利基中的使用使得PDL用户的生活更加轻松.