Вопрос

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

Спасибо

Это было полезно?

Решение

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

Другие советы

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

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

Тогда позже:

$foo->x = 5;

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

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

$foo->{x} = 5;

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

$foo->set_x(5);

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

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

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top