2015-07-06 7 views
3

Есть следующий код safe? Выполняется ли она во всех версиях perl> = 5.8? Гарантировано ли, что сдвиги выполнены до @_ не распакованы?Можно ли использовать shift и @_ в том же самом заявлении?

sub f1 { 
    shift->update(p1 => shift, p2 => shift, @_); 
} 

Многословный альтернативный код:

sub f2 { 
    my ($self, $p1, $p2, @r) = @_; 
    $self->update(p1 => $p1, p2 => $p2, @r); 
} 
+2

safe ≠ readable – choroba

+2

Если вы не пытаетесь выиграть в гольф, сделайте подробный. –

ответ

6

Он ведет себя правильно во всех существующих Perl переводчиков.

Однако порядок оценки операндов оператора запятой документируется, когда он используется в скалярном контексте, но не для тех случаев, когда он используется в контексте списка в данном случае. Хуже того, это недокументированное поведение в области, которая является неопределенным поведением на некоторых других языках. Я не вижу, как меняется поведение, но это тоже небезопасно.

Компромисс:

sub f3 { 
    my $self = shift; 
    my $p1 = shift; 
    my $p2 = shift; 

    $self->update(p1 => $p1, p2 => $p2, @_); 
} 

Если вы абсолютно хотели пойти с переменной менее, вы можете смело использовать следующее:

sub f4 { $_[0]->update(p1 => $_[1], p2 => $_[2], @_[3..$#_]) } 

Я не знаю, почему вы хотели бы использовать что , хоть. Трудно читать, даже не считая потери самодокументирующих свойств именования параметров.

+0

Я помню только, что perl6 с этим явным неопределенным поведением, чтобы иметь возможность распараллеливать его, но я не вижу никаких шансов, что perl5 когда-либо оставит вас вправо, чтобы оценить списки аргументов. – rurban