在Perl中lvalue子例程有什么用?

时间:2009-02-02 20:56:32

标签: perl subroutine lvalue

我不明白lvalue子程序的用途是什么?用普通子程序无法完成的是什么?你能发一些例子吗?

由于

4 个答案:

答案 0 :(得分:19)

您可以将lvalue subs用作对象成员的设置者:

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的使用是“奇怪的”,并且由于它的陌生性而无法获得直观性的任何东西。

答案 1 :(得分:14)

建议避免使用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子)。我不认为它,但它含糊不清我必须检查手册,以记住它是否有,这是不好的。

答案 2 :(得分:8)

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

lvalue_sub($foo) =~ s/foo/bar/;

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

答案 3 :(得分:6)

我不能说我在普通的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用户的生活更容易