2013-06-01 37 views
14

Tôi biết một chút perl, nhưng không đủ sâu để hiểu tiếp theo.Mã perl lạ - tìm kiếm giải thích

Đọc perldelta 5.18 tôi tìm thấy đoạn mã tiếp theo là đã bị vô hiệu hóa trong 5,18. Không đếm điều này, vẫn muốn hiểu nó hoạt động như thế nào.

Đây là mã và trong các ý kiến ​​là những gì tôi hiểu

%_=(_,"Just another "); #initialize the %_ hash with key=>value _ => 'Just another' 
$_="Perl hacker,\n"; #assign to the $_ variable with "Perl..." 
s//_}->{_/e;   # darkness. the /e - evauates the expression, but... 
print 

nó in:

Just another Perl hacker, 

tôi đã cố gắng, các perl -MO=Deparse và nhận tiếp theo

(%_) = ('_', 'Just another '); #initializing the %_ hash 
$_ = "Perl hacker,\n";   # as above 
s//%{'_';}/e;     # substitute to the beginning of the $_ - WHAT? 
print $_;      # print the result 
japh syntax OK 

gì là lạ (ít nhất là đối với tôi) - chạy mã "deparsed" không cho kết quả ban đầu và pr ints:

1/8Perl hacker, 

tôi sẽ rất hạnh phúc:

  1. nếu ai đó có thể giải thích mã, đặc biệt là nếu ai đó có thể viết một mã helper, (với các bước bổ sung) những gì giúp tôi hiểu nó như thế nào là công trình - chuyện gì xảy ra.
  2. giải thích, tại sao mã không được in ra không in kết quả ban đầu.

Điều gì có nghĩa là số %{'_';} trong mã bị thiếu?

+2

Tôi không thể giải thích mọi thứ, nhưng vì lý do nào đó '' _} -> {_ '' trong regex tương đương với '' $ {_} {_} '' (tự nó có vẻ vui, nhưng không phải quá không đọc được). – mzedeler

+0

Những gì tôi không nhận được là làm thế nào các nhà điều hành mũi tên bằng cách nào đó được gobbled lên, bởi vì nó chỉ nên làm việc nếu '' $ _'' là một tham chiếu băm. – mzedeler

Trả lời

14

Mã thực sự được thực hiện bởi các nhà điều hành thay thế có lẽ là thực sự cái gì đó như

my $code = "do { $repl_expr }"; 

Vì vậy, khi các biểu hiện thay thế là _}->{_, sau đây được thực hiện:

do { _}->{_ } 

_ chỉ đơn giản trả về chuỗi _ (kể từ khi bị tắt nghiêm ngặt), do đó, giống như

do { "_" }->{_} 

mà là giống như

"_"->{_} 

Những gì bạn có có một dereference yếu tố băm, nơi tham chiếu là một tài liệu tham khảo biểu tượng (ví dụ: một chuỗi thay vì tham chiếu thực tế). Thông thường cấm nghiêm ngặt, sau đây là một ví dụ về một tài liệu tham khảo mang tính biểu tượng tại nơi làm việc:

%h1 = (id => 123); 
%h2 = (id => 456); 
print "h$_"->{id}, "\n" 
    for 1..2; 

Vì vậy, đó có nghĩa là

"_"->{_} # Run-time symbol lookup 

cũng giống như

$_{_}  # Compile-time symbol lookup 

Một thủ thuật tương tự là thường được sử dụng trong một lớp lót.

perl -nle'$c += $_; END { print $c }' 

có thể được rút ngắn xuống còn

perl -nle'$c += $_; }{ print $c' 

Bởi vì mã được thực thi khi -n được sử dụng được lấy từ một cái gì đó tương đương với

my $code = "LINE: while (<>) { $program }"; 

%{'_';} 

là rất lạ cách viết

%{'_'} 

là một tham số băm. Một lần nữa, tham chiếu ở đây là một tham chiếu tượng trưng. Nó tương đương với

%_ 

Trong bối cảnh vô hướng, băm hiện trả về một giá trị mà báo cáo một số thông tin về internals của băm đó (hoặc một giá trị false nếu trống). Đã có một gợi ý để thay đổi nó để trả về số lượng các phím thay thế.

+0

Bởi vì nó cố gắng bỏ qua 'do' hoặc bất cứ điều gì đã được thêm vào bởi biểu thức thay thế, nhưng kết thúc lên bỏ qua một cái gì đó khác vì' do' không phải là op đầu tiên nữa. – ikegami

+0

Hoặc trong các thuật ngữ tổng quát hơn, mã tạo mã được biên dịch không bao giờ tồn tại, do đó một giả định mà Deparse tạo ra là không thành công. – ikegami

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