2009-02-02 16 views

Odpowiedz

15

lwartościami zaleca się unikać. Są zabawne i wszystkie, ale mylą nowych użytkowników, którzy przyjmują założenia o tym, jak działają wszystkie subwoofery, a zatem powinno się ich unikać w kodzie, gdy dostępny jest lepszy sposób.

Czasami niezwykle użyteczne może być użycie wyniku LValue do brudnej pracy.

substr($string, $start, $stop) = 'somevalue' # replaces the specified part of the substring. 

Jednak to robi też to samo:

substr($string, $start, $stop , 'somevalue'); 

Różnica tutaj jest przeważnie były znacznie bardziej wyrazistą moc, ponieważ delegatów zachowanie do kodu, który używa go zamiast sama funkcja.

Na przykład:

substr($string, $start, $stop) =~ s/a/b/g 

wymagają, aby zrobić

my $x = substr($string, $start, $stop); 
$x =~ s/a/b/g/; 
substr($string, $start, $stop, $x); 

co jest trochę przykre.

Chociaż jest tu jeszcze coś nieprzyjemnego, ponieważ trzeba się zastanowić, czy dokonanie tej zamiany, czy nie za pomocą $ x, działa wstecz, aby zmodyfikować ciąg znaków lub nie (z powodu substr jest podrzędnym LValue). Nie sądzę, żeby tak było, ale na tyle niejednoznacznie muszę sprawdzić instrukcję, aby pamiętać, czy tak jest, czy nie, i to jest złe.

+2

$ x zawiera kopię, a nie l-wartości. Ale jeśli alias l-substr substr ala 'for (substr (...)) {' lub 'foo (substr (...))' możesz zrobić więcej niż jedną rzecz z lwartością. – ysth

+0

Mam problem ze zrozumieniem niektórych z twoich zwrotów: A) "aby użyć wyniku LV do wykonania brudnej pracy." ale nie widzę, że ilustrowane w przykładzie - lub nie rozumiem, co masz na myśli przez "wynik LValue" B) ", ponieważ deleguje zachowanie do kodu, który używa go zamiast samej funkcji." może chodzi o bycie obcym angielskim, ale jestem zdezorientowany co do znaczenia zaimków tutaj –

+0

i C) "ponieważ musisz pomyśleć o tym, czy dokonanie tej zamiany, czy nie z $ x działa wstecz, aby zmodyfikować ciąg znaków, czy nie" - zbyt niejasne dla mnie, nie może nawet wskazać, jak dokładnie ... –

7

Stanowią one inny interfejs, który w pewnych okolicznościach może być bardziej intuicyjna. W przeciwieństwie do tradycyjnych seterów, możesz zmienić wartość bezpośrednio. Na przykład

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

może być czystsze niż

my $tmp = some_sub($foo); 
$tmp =~ s/foo/bar/; 
some_sub($foo, $tmp); 
17

Można użyć lwartość subs jak ustawiaczy dla członków obiektu:

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

Później:

$foo->x = 5; 

ten łączy w sobie intuicyjną ustawiania członków bezpośrednio z elastycznością enkapsulacji setter, w przypadku później chcesz zmienić sposób implementacji obiektu. Porównaj z poniższymi bardziej tradycyjnymi sposobami ustawiania członków w Perlu:

Intuicyjna, ale delikatna; co jeśli zmienisz sposób wdrażania $ foo?

$foo->{x} = 5; 

Tradycyjna metoda setera; nie używa składni przypisania do jakiej ilości do zadania:

$foo->set_x(5); 

Oczywiście, metody lwartości naprawdę nigdy nie została przyjęta przez społeczność Perl, a korzystanie z lwartości Subs to „dziwne” i cokolwiek by zyskać na intuicyjność byłaby zagubiona przez dziwność tego wszystkiego.

+1

Należy zauważyć, że podobnie jak [instrukcja] (https://perldoc.perl.org/perlsub.html#Lvalue-subroutines) stwierdza, za pomocą subwooferów lwartości dla setery takie jak to wykluczają możliwość sprawdzania poprawności danych wejściowych. Innymi słowy, używanie podrzędnych lwartości jako akcesorów jest znacznie mniej skuteczne niż zwykła metoda. –

6

Nie mogę mówić za korzystanie z nich w normalnych rzeczach Perla, ale są one szeroko stosowane w języku danych Perla podczas robienia plasterków lub innych podsekcji piddle. Na przykład:

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; 

jak wiele rzeczy w Perlu, funkcja ta nie jest używana znacznie w całym ekosystemie, ale jego użycie przynajmniej w tej niszy czyni życie znacznie łatwiejsze dla użytkowników PDL.

+0

Musiałem przegłosować twoją pierwszą odpowiedź! –

Powiązane problemy