2014-09-10 25 views
7

Bất cứ khi nào tôi muốn mô phỏng đầu vào và đầu ra cho một filehandle, tôi sẽ thường xuyên sử dụng tài liệu tham khảo để DATASTDOUT tương ứng:Sự khác nhau giữa * DATA và * DỮ LIỆU

use strict; 
use warnings; 
use autodie; 

#open my $infh, '<', 'infile.txt'; 
my $infh = \*DATA; 

#open my $outfh, '>', 'outfile.txt'; 
my $outfh, \*STDOUT; 

print $outfh <$infh>; 

__DATA__ 
Hello World 

Đầu ra:

Hello World 

Tuy nhiên, trong một số recent answer bởi Borodin, nó đã được chứng minh rằng nó không thực sự cần thiết để tham khảo. Thay vào đó, một nhiệm vụ đơn giản là đủ:

my $infh = *DATA; 

Vì vậy, tôi đã tạo ra kịch bản sau đây để so sánh và đối chiếu sự khác biệt giữa hai phương pháp:

use strict; 
use warnings; 

use Fcntl qw(:seek); 

# Compare Indirect Filehandle Notation 
my %hash = (
    '\*DATA' => \*DATA, 
    '*DATA' => *DATA, 
); 

my $pos = tell DATA; 

my $fmt = "%-8s %-22s %-7s %s\n"; 
printf $fmt, qw(Name Value ref() readline()); 

while (my ($name, $fh) = each %hash) { 
    seek($fh, $pos, SEEK_SET); # Rewind FH 
    chomp(my $line = <$fh>); 
    printf $fmt, $name, $fh, ref($fh), $line; 
} 

__DATA__ 
Hello World 

Đầu ra:

Name  Value     ref() readline() 
\*DATA GLOB(0x7fdc43027e70) GLOB Hello World 
*DATA *main::DATA     Hello World 

Khi nó đi qua và đọc từ filehandle, không có sự khác biệt giữa typeglob và tham chiếu đến typeglob.

Chuyển từ thử nghiệm mẫu nghiên cứu điều tra cho thấy các trang perldoc sau:

Tham chiếu đầu tiên cho thấy một trong hai cách sử dụng. Trong khi thứ hai đưa ra một danh sách các lựa chọn thay thế khác, nhưng đề cập đến cách ký hiệu tham chiếu là cần thiết nếu chúng ta muốn ban phước cho biến đó. Không có sự khác biệt nào khác được đề xuất.

Có sự khác biệt về phong cách chức năng hoặc ưa thích của hai tệp gián tiếp gián tiếp này không?

  1. my $fh = \*DATA;
  2. my $fh = *DATA;
+2

Phản ứng tức thì của tôi là mọi nhân vật phụ đều bổ sung thêm chút tiềm năng cho sự nhầm lẫn ở đâu đó trên đường ... – abiessu

+0

nhiều nơi cũng chấp nhận một ioref ('* DATA {IO}') – ysth

+2

@abiessu, tôi muốn nói mà không phù hợp với những gì 'mở $ fh' trả về của tôi thực sự có nhiều khả năng gây nhầm lẫn. – ikegami

Trả lời

9

Một là một glob; của một tham chiếu đến một glob. Hầu hết các địa điểm đều chấp nhận cả hai. Nhiều người cũng chấp nhận tên của glob như một chuỗi, và nhiều người chấp nhận một tham chiếu đến một đối tượng IO.

# Symbolic reference to the glob that contains the IO object. 
>perl -E"$fh = 'STDOUT'; say $fh 'hi'" 
hi 

# Reference to the glob that contains the IO object. 
>perl -E"$fh = \*STDOUT; say $fh 'hi'" 
hi 

# Glob that contains the IO object. 
>perl -E"$fh = *STDOUT;  say $fh 'hi'" 
hi 

# Reference to the IO object. 
>perl -E"$fh = *STDOUT{IO}; say $fh 'hi'" 
hi 

open(my $fh, '<', ...) populates $fh với một tham chiếu đến một glob, và đó là hỗ trợ hầu hết, vì vậy đó là những gì tôi sử dụng nếu tôi phải chọn.

+0

Tôi rất vui khi biết rằng không có bất kỳ cạm bẫy chức năng nào cần phải lo lắng. Điểm cuối cùng của bạn về việc phản chiếu 'mở $ fh' của tôi rất hữu ích từ phối cảnh kiểu. Ngoài ra, vì hầu hết thời gian tôi đang cố gắng lập mô hình mã cho người mới bắt đầu, có thể cũng hữu ích khi chứng minh việc sử dụng tài liệu tham khảo vì chúng tôi không nhầm lẫn chúng với ngoại lệ đối với quy tắc về cách chuyển cấu trúc dữ liệu phức tạp. – Miller

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