Каковы функции lvalue в Perl? - PullRequest
       11

Каковы функции lvalue в Perl?

16 голосов
/ 02 февраля 2009

Я не понимаю, в чем может быть смысл использования подпрограмм lvalue? Что я не могу сделать с помощью обычных подпрограмм? Не могли бы вы опубликовать несколько примеров?

Спасибо

Ответы [ 4 ]

19 голосов
/ 03 февраля 2009

Вы можете использовать подпрограммы lvalue в качестве сеттеров для членов объекта:

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

Потом позже:

$foo->x = 5;

Это сочетает в себе интуитивность установки элементов напрямую с гибкостью инкапсуляции установщика, на случай, если позже вы захотите изменить способ реализации объекта. Сравните со следующими более традиционными способами установки элементов в Perl:

Интуитивно понятный, но хрупкий; что если вы измените способ реализации $ foo?

$foo->{x} = 5;

Традиционный метод сеттера; не использует синтаксис назначения для того, что составляет назначение:

$foo->set_x(5);

Конечно, методы lvalue никогда не были приняты сообществом Perl, и использование подпрограмм lvalue "странно", и все, что можно было бы получить для интуитивности, было бы потеряно из-за странности всего этого.

14 голосов
/ 03 февраля 2009

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). Я не думаю, что это так, но это достаточно неоднозначно, я должен проверить руководство, чтобы вспомнить, делает ли это или нет, и это плохо.

8 голосов
/ 03 февраля 2009

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

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

может быть чище, чем

my $tmp = some_sub($foo);
$tmp =~ s/foo/bar/;
some_sub($foo, $tmp);
6 голосов
/ 15 января 2012

Я не могу говорить за то, что использовал их много в моем обычном Perl, но они широко используются в языке данных Perl, когда берут кусочки или другие подразделы piddle. Например:

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.

...