2011-12-09 40 views
14

Tôi muốn tạo tham chiếu đến một mảng thu được bằng cách chia nhỏ trong Perl. Tôi đang nghĩ đến một cái gì đó như:Làm thế nào để tham chiếu một biểu thức tách trong Perl?

my $test = \split(/,/, 'a,b,c,d,e'); 

foreach $k (@$test) { 
    print "k is $k\n"; 
} 

Nhưng đó phàn nàn với Not an ARRAY reference at c:\temp\test.pl line 3. Tôi đã thử một vài lựa chọn thay thế khác, tất cả không thành công.

Trả lời

31

nền giải thích:

split, giống như các chức năng khác, trả về một danh sách. Bạn không thể tham chiếu đến một danh sách. Tuy nhiên, nếu bạn áp dụng toán tử tham chiếu vào danh sách, nó sẽ được áp dụng cho tất cả các thành viên của nó. Ví dụ:

use Data::Dumper; 

my @x = \('a' .. 'c'); 

print Dumper \@x 

Output:

$VAR1 = [ 
      \'a', 
      \'b', 
      \'c' 
     ];

Vì vậy, khi bạn viết my $test = \split(/,/, 'a,b,c,d,e');, bạn sẽ có được một tham chiếu đến các yếu tố cuối cùng của danh sách trả lại (xem, ví dụ, What’s the difference between a list and an array?). tình hình của bạn là tương tự như:

Mặc dù có vẻ như bạn có một danh sách ở phía bên tay phải, Perl thực sự nhìn thấy một loạt các vô hướng tách bằng dấu phẩy:

my $scalar = ('dog', 'cat', 'bird'); # $scalar gets bird 

Vì bạn đang gán cho một vô hướng, phía bên phải là trong ngữ cảnh vô hướng. Toán tử dấu phẩy (có, nó là toán tử!) Trong ngữ cảnh vô hướng đánh giá bên trái của nó, ném đi kết quả, và đánh giá nó là bên tay phải và trả về kết quả. Trong thực tế, danh sách giống như cái này gán cho $ scalar là giá trị cao nhất bên phải. Nhiều người đống lộn xộn này lên, vì họ chọn một danh sách-lookalike có yếu tố cuối cùng cũng là số họ mong đợi:

my $scalar = (1, 2, 3); # $scalar gets 3, accidentally 

Trong trường hợp của bạn, những gì bạn nhận được trên RHS là danh sách các tài liệu tham khảo để các yếu tố của danh sách được trả lại bởi split và phần tử cuối cùng của danh sách đó kết thúc bằng số $test. Trước tiên, bạn cần phải xây dựng một mảng từ các giá trị trả về đó và tham chiếu đến giá trị đó. Bạn có thể làm điều đó một câu lệnh bằng cách hình thành một mảng vô danh và lưu trữ các tài liệu tham khảo để rằng trong $test:

my $test = [ split(/,/, 'a,b,c,d,e') ]; 
+0

Đây là lý do tại sao tôi yêu SO! Cảm ơn rất nhiều vì sự giải thích kỹ lưỡng, kiên nhẫn và rất rõ ràng của bạn. Nó hoàn toàn rõ ràng bây giờ, tôi đã học được rất nhiều ngày hôm nay. Cảm ơn! –

19

Xung quanh split lệnh giữa dấu ngoặc vuông để tạo tham chiếu ẩn danh.

my $test = [ split(/,/, 'a,b,c,d,e') ]; 
+0

Cảm ơn tôi là một chút đánh lừa với các ví dụ dấu chéo ngược trong cuốn sách perl của tôi. –

+1

Đây có phải là hiệu quả khi lưu trữ kết quả tách trong var '@ splitResult', sau đó tham chiếu đến biến đó với' $ arrayRef = \ @ splitResult'? Hoặc là mảng được khởi tạo hai lần? Một lần trong quá trình chia tách và một lần nữa để khởi tạo ref mảng ẩn danh. – Despertar

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