2009-02-02 22 views

Trả lời

15

lvalues ​​được khuyến khích để tránh. Họ vui vẻ và tất cả, nhưng họ làm lẫn lộn những người dùng mới, những người đưa ra giả định về cách tất cả các hoạt động của người đăng ký và do đó cần tránh mã khi có cách tốt hơn.

Đôi khi có thể cực kỳ thiết thực khi sử dụng kết quả LValue để thực hiện công việc bẩn.

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

Tuy nhiên, điều này cũng làm điều tương tự:

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

Sự khác biệt ở đây là hầu hết các cựu đã điện đáng kể diễn cảm hơn, vì nó đại biểu các hành vi vào mã có sử dụng nó thay cho chính nó.

Ví dụ:

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

sẽ yêu cầu bạn phải làm

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

Đó là một chút khó chịu.

Mặc dù, có thêm một sự khó chịu ở đây, vì bạn phải suy nghĩ về việc làm thay thế hay không với $ x hoạt động hồi tố để sửa đổi chuỗi hoặc không (do nền là một phụ LValue). Tôi không nghĩ rằng nó có, nhưng không rõ ràng của nó, tôi phải kiểm tra hướng dẫn để nhớ liệu nó có hay không, và đó là xấu.

+2

$ x chứa một bản sao chứ không phải một giá trị. Nhưng nếu bạn bí danh một nền lvalue ala 'cho (substr (...)) {' hoặc 'foo (substr (...))' bạn có thể làm nhiều hơn một điều với lvalue. – ysth

+0

Tôi đang gặp sự cố khi hiểu một số cụm từ của bạn: A) "để sử dụng kết quả LValue để thực hiện công việc bẩn thỉu." nhưng tôi không thể thấy rằng ilustrated trong ví dụ - hoặc tôi không hiểu những gì bạn có nghĩa là "một kết quả LValue" B) "vì nó đại biểu cho hành vi mã sử dụng nó thay vì chức năng chính nó." có lẽ đó là về tiếng Anh không phải là tiếng mẹ đẻ, nhưng tôi nhầm lẫn về ý nghĩa của đại từ ở đây –

+0

và C) "bởi vì bạn phải suy nghĩ về việc làm thay thế hay không với $ x hoạt động hồi tố để sửa đổi chuỗi hay không" - quá không rõ ràng với tôi, thậm chí không thể chỉ ra chính xác ... –

7

Chúng cung cấp giao diện khác, trong một số trường hợp có thể trực quan hơn. Không giống như setters truyền thống, bạn thực sự có thể thay đổi giá trị trực tiếp. Ví dụ

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

có thể sạch hơn

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

Bạn có thể sử dụng giá trị trái tàu ngầm như setters cho các thành viên đối tượng:

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

Rồi sau:

$foo->x = 5; 

này kết hợp intuitiveness thiết các thành viên trực tiếp với sự linh hoạt của đóng gói setter, trong trường hợp sau đó bạn muốn thay đổi cách đối tượng được triển khai. So sánh với các cách truyền thống sau đây để đặt thành viên trong Perl:

Trực quan nhưng mong manh; nếu bạn thay đổi cách thực hiện $ foo thì sao?

$foo->{x} = 5; 

Phương thức setter truyền thống; không sử dụng cú pháp gán cho những gì số tiền chuyển nhượng:

$foo->set_x(5); 

Dĩ nhiên, phương pháp giá trị trái chưa bao giờ thực sự được chấp nhận bởi cộng đồng Perl, và sử dụng các tàu ngầm vế trái là "kỳ lạ" và bất cứ điều gì sẽ đạt được cho intuitiveness sẽ bị mất bởi sự kỳ lạ của tất cả.

+1

Lưu ý rằng giống như trạng thái [thủ công] (https://perldoc.perl.org/perlsub.html#Lvalue-subroutines), sử dụng các giá trị lvalue cho setters như thế này ngăn cản khả năng xác thực đầu vào. Nói cách khác, việc sử dụng các giá trị lvalue subs như các bộ tiếp cận là ít mạnh hơn một phương thức đơn giản. –

6

Tôi không thể nói về việc sử dụng chúng nhiều trong công cụ Perl bình thường của mình, nhưng chúng được sử dụng rộng rãi trong Ngôn ngữ dữ liệu Perl khi lấy lát hoặc các phần phụ khác của piddle. Ví dụ:

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; 

Giống như nhiều điều trong Perl, tính năng này không được sử dụng nhiều trên toàn bộ hệ sinh thái, nhưng việc sử dụng nó ít nhất trong niche này làm cho cuộc sống nhiều dễ dàng hơn cho người dùng của PDL.

+0

Tôi đã phải đưa ra câu trả lời đầu tiên của bạn! –

Các vấn đề liên quan