2010-10-25 31 views
7
print <<EOF 
stuff 
EOF 
; 


print <<EOF; 
stuff 
EOF 

Tại sao bạn nên sử dụng cái kia?Sự khác biệt giữa hai đoạn mã Perl này là gì?

+3

Tôi thích công cụ đầu tiên để làm quen với động cơ thụt lề của emacs. – mob

+3

Tôi nghĩ rằng đây là một câu hỏi đủ trung thực, không chủ quan/tranh luận. – Zaid

+0

Như mọi khi, ** TIMTOWTDI ** :-). –

Trả lời

14

Hai ví dụ lên tới điều tương tự behaviourally, nhưng xem xét nếu bạn muốn làm một cái gì đó khác sau khi in mà khối:

print <<EOF 
stuff 
EOF 
. "more text here"; 

... hoặc có thể bạn cần phải kiểm tra kết quả của các hoạt động:

print $unstable_filehandle <<EOF 
stuff 
EOF 
or warn "That filehandle finally disappeared: $!"; 

Các ví dụ này được giả tạo, nhưng bạn có thể thấy đôi khi hữu ích khi linh hoạt về mã nào sau khối văn bản.

2

FWIW, Perl Thực tiễn tốt nhất khuyến cáo:

print <<'EOF'; 
stuff 
EOF 
+1

Không giống nhau. Các dấu nháy đơn ngăn chặn nội suy. Tương đương với câu hỏi sẽ có dấu ngoặc kép. – igelkott

+2

@igelkott: và pbp khuyến cáo các dấu nháy đơn khi không có bất kỳ phép nội suy nào :) – ysth

+0

Không có nội suy nào xảy ra trong OP. –

4

Bạn nên xử lý heredoc mã thông báo chính xác như xâu mà họ đang có. Đừng trì hoãn thêm dấu chấm câu hoặc cú pháp cho đến sau nội dung của chúng. Đó là gây hiểu lầm và dễ bị lỗi. Đây được mười ví dụ tất cả lấy từ mã thực:

  1. ($is_a_valid_rfc_822_addr = <<'EOSCARY') =~ s/\n//g;
  2. $eval = (($Preamble=<<'END1') . $userstuff . <<'END2');
  3. for my $line (<<"End_of_Property_List" =~ m{ \S .* \S }gx) {
  4. $cases .= <<"EDQ" if $timeout;
  5. ($is_a_valid_rfc_822_addr = <<'EOSCARY') =~ s/\n//g;
  6. eval (($Preamble=<<'END1') . $_[0] . <<'END2');
  7. @changes = split("\n", <<"EOCHANGES");
  8. $change .= sprintf(<<"EOP", $in, $out, $in, $out);
  9. eval "{ package $package; " . <<'EOF' . "}";
  10. push @args, dequeue('|Q|', <<'END_OF_ASTRAL_MATCH') if $Opt{astral};

Xem cách mà làm việc?

9

Như tchrist chỉ ra, một điều mà hầu hết mọi người bỏ bê là toán tử heredoc mất mã perl tùy ý sau mã chấm dứt.

này có nghĩa rằng bạn có thể làm (cho là) ​​thao tác tìm kiếm tự nhiên hơn, chẳng hạn như:

my $obj = Foo::Bar->new(content => <<EOP)->do_stuff->sprint(); 
    This is my content 
    It's from a heredoc. 
EOP 

Một hệ quả là bạn còn có thể ngăn xếp chúng MUCH nhiều readably (theo ý kiến ​​của tôi;) so với "unstacked" :

-- stacked_heredoc.pl 
#!/usr/bin/perl 
use strict; 
use warnings; 

print join(<<JOINER, split("\n", <<SOURCE)); 

------------------------------ 
JOINER 
This is my text 
this is my other text 
a third line will get divided! 
SOURCE 

câu một heredoc unstacked ...

-- unstacked_heredoc.pl 
#!/usr/bin/perl 
use strict; 
use warnings; 

my $joiner = <<JOINER 

------------------------------ 
JOINER 
; 

my $source = <<SOURCE 
This is my text 
this is my other text 
a third line will get divided! 
SOURCE 
; 

print join($joiner, split("\n", $source)); 
1

Randal Schwartz có gr ăn bài viết ở đây tài liệu HERE.

Có một vài điều cần nhớ về đây tài liệu:

  1. Các ; trong Perl là terminator tuyên bố và là cần thiết cho tất cả các câu Perl (với một số ngoại lệ) bao gồm các tài liệu ở đây chuỗi;
  2. Tài liệu ở đây là một câu nói vui vẻ thực sự chỉ là một chuỗi lớn;
  3. Phải có CR kết thúc đối với tài liệu tại đây (không giống như hầu hết các báo cáo Perl khác);
  4. Bạn có thể có mã Perl tùy ý ngay sau thẻ mở hoặc sau thẻ đóng. Nếu sau thẻ đóng, thẻ phải nằm trên một dòng riêng biệt. Trong cả hai trường hợp, mã hoạt động trên văn bản của chuỗi ở đây;
  5. Dấu ngoặc kép bạn sử dụng trên thẻ ảnh hưởng đến chuỗi. Dấu ngoặc kép giống như chuỗi trích dẫn kép trong Perl, dấu nháy đơn không nội suy, dấu ngoặc kép trở lại được chuyển đến trình bao. Không có dấu ngoặc kép nào tương đương với dấu ngoặc kép;
  6. TIMTOWTDI, nhưng một số biểu mẫu khó đọc;
  7. Trích dẫn từ perldoc -q "HERE documents" (và perlfaq4):

    Có phải là không có không gian sau khi phần < <.

    Có (có thể) phải là dấu chấm phẩy ở cuối [của phần <<].

    Bạn không thể (dễ dàng) có bất kỳ khoảng trống nào trước thẻ.

Hai hình thức bạn có tương đương về mặt chức năng. Cũng giống như { ... } if (blah blah) cũng giống như if (blah blah) { ... }. Trong khi hai câu lệnh này có tính tương đương về chức năng thì chúng "đọc" một cách khác nhau.

Mỗi trong số này là tương đương và hợp lệ Perl đây tài liệu:

my %data = <<END 
fred: Fred Flintstone 
barney: Barney Rubble 
betty: Betty Rubble 
wilma: Wilma Flintstone 
END 
=~ /(\w+): (.*)/g; 

my %data = <<END =~ /(\w+): (.*)/g; 
fred: Fred Flintstone 
barney: Barney Rubble 
betty: Betty Rubble 
wilma: Wilma Flintstone 
END 

# You must have a CR after the "END". Can't be EOF... 

Cả hai thiết lập %data băm để first=>"full name" cho Flintstones. Mà bạn sẽ thấy trong mã đến với bạn? Lưu ý hình thức thứ hai là một trong những nơi có một gotcha: Có cần phải được văn bản hoặc khoảng trắng sau khi chấm dứt đánh dấu hoặc bạn có thể nhận được Can't find string terminator "END" anywhere before EOF Tôi nghĩ rằng đó là lý do tại sao bạn nhìn thấy đơn độc ; trên tài liệu của một số người ở đây.

IMHO, ; thuộc về trường hợp đầu tiên của thẻ tài liệu tại đây hoặc mã tuân theo nó. Sẽ khó đọc hơn nếu nó sau thẻ đóng. Trừ khi thẻ đóng trong biểu mẫu tương tự như công cụ sửa đổi câu lệnh hoặc cảnh báo hoặc logic chết. Đó chỉ là hướng dẫn về phong cách cá nhân của tôi.

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