2011-07-06 22 views
8

Trong Perl, là có bao giờ bất kỳ sự khác biệt giữa hai cấu trúc sau:Trong Perl, có bất kỳ sự khác biệt nào giữa việc tạo bí danh và tạo bí danh trực tiếp qua stash không?

*main::foo = *main::bar 

$main::{foo} = $main::{bar} 

Họ dường như có chức năng tương tự (aliasing tất cả các khe trong *main::foo tượng quy định tại *main::bar), nhưng tôi chỉ tự hỏi nếu tương đương này luôn luôn giữ.

+3

Tôi tò mò điều gì đã mang lại điều này. :) –

+1

Nguyên nhân trước đây gây ra lỗi khi được bật 'nghiêm ngặt' hoặc nghiêm ngặt. – MkV

+1

Tôi đã viết một vòng lặp để bí danh một vài tên phương thức với nhau và bắt đầu tự hỏi tại sao tôi luôn viết '{no strict' refs '; * {'some :: pkg'. $ new} = * {'một số :: pkg'. $ cũ} 'khi' $ một số :: pkg :: {$ new} = $ một số :: pkg :: {$ cũ } 'cũng sẽ hoạt động tốt. Trực giác chúng có vẻ giống nhau, nhưng những thứ như quan hệ/quá tải/ma thuật khác có thể có hậu quả "thú vị" nếu chúng xử lý bản sao khác nhau, hoặc là lỗi hoặc hành vi dự định. –

Trả lời

9

Có lẽ không phải là loại chênh lệch bạn đang tìm kiếm, nhưng có hai sự khác biệt lớn giữa *main::foo$main::{foo}; các cựu nhìn lên glob trong stash lúc biên dịch thời gian, tạo ra nó nếu cần thiết, trong khi sau này sẽ cho glob trong stash tại thời gian chạy, và sẽ không tạo ra nó.

Điều này có thể tạo ra sự khác biệt với bất kỳ điều gì khác trong trò chơi, và chắc chắn có thể ảnh hưởng đến việc bạn nhận được cảnh báo used only once hay không.

+0

Đối với những người như tôi, những người không vào bí mật Perl: [Stashes and Globs] (http://www.perlmonks.org/?node=perlguts#Stashes_and_Globs): "* Stash là một băm chứa tất cả các đối tượng khác nhau Mỗi khóa của stash là một tên biểu tượng (được chia sẻ bởi tất cả các loại đối tượng khác nhau có cùng tên) và mỗi giá trị trong bảng băm là GV (Giá trị Glob). lần lượt chứa tham chiếu đến các đối tượng khác nhau của tên đó * "... chuyến đi Perl không bao giờ kết thúc! –

+0

@DavidTonhofer đặc biệt vì điều đó không hoàn toàn chính xác; trong một số trường hợp, stash có thể có giá trị không phải là GV. – ysth

3

Các kịch bản sau đây:

#!/usr/bin/env perl 

#mytest.pl 

no warnings; 


$bar = "this"; 
@bar = qw/ 1 2 3 4 5 /; 
%bar = qw/ key value /; 

open bar, '<', 'mytest.pl' or die $!; 

sub bar { 
    return "Sub defined as 'bar()'"; 
} 
$main::{foo} = $main::{bar}; 

print "The scalar \$foo holds $foo\n"; 
print "The array \@foo holds @foo\n"; 
print "The hash \%foo holds ", %foo, "\n"; 
my $line = <foo>; 
print "The filehandle 'foo' is reads ", $line; 
print 'The function foo() replies "', foo(), "\"\n"; 

Đầu ra:

The scalar $foo holds this 
The array @foo holds 1 2 3 4 5 
The hash %foo holds keyvalue 
The filehandle 'foo' is reads #!/usr/bin/env perl 
The function foo() replies "Sub defined as 'bar()'" 

Vì vậy, nếu *main::foo = *main::bar; không làm điều tương tự như $main::{foo} = $main::{bar};, tôi đang ở một mất mát như thế nào để phát hiện một thực tế Sự khác biệt. ;) Tuy nhiên, từ góc độ cú pháp, có thể có những tình huống dễ sử dụng hơn so với phương pháp khác. ... các cảnh báo thông thường về việc nhét xung quanh trong bảng biểu tượng luôn luôn áp dụng.

+0

phỏng đoán của tôi là bất kỳ sự khác biệt nào (nếu có) sẽ có một số phép thuật bí truyền hoặc thuật toán bộ nhớ đệm quá mức.cú pháp có sự khác biệt rõ ràng, mã từ việc gán glob cùng với 'refrict'' không nghiêm ngặt trong một thường trình' import' ngắn hơn một chút (và nhanh hơn) bằng cách lấy người gọi một cách thủ công và đi bộ mức biểu tượng theo cấp độ, dẫn tôi thích cú pháp glob hơn, nhưng khi viết cho một tên đầy đủ được biết trước (hoặc đã xử lý một stash vì một số lý do khác), sự khác biệt cú pháp là một chút murkier, do đó câu hỏi :) –

+1

Tìm kiếm dưới mui xe là một sự chuyển hướng thú vị. Tôi nghĩ rằng có những tình huống mà ký hiệu glob cũ tốt là rõ ràng nhất, trong khi có những tình huống khác khi ký hiệu $ namespace :: {key} rõ ràng hơn. Cho dù ai là rõ ràng hơn cho một nhu cầu cụ thể, đó là cách để làm điều đó. :) Tất nhiên nếu một người có thể tìm thấy một thay thế để lội qua bảng biểu tượng có rất nhiều lý do để tránh một trong hai cách tiếp cận bằng cách thiết kế. – DavidO

3

Truy cập stash là $A::{foo} = $obj cho phép bạn đặt bất kỳ thứ gì lên bảng biểu tượng trong khi *A::foo = $obj địa điểm $obj trên khe mong đợi của typeglob theo loại $obj.

Ví dụ:

DB<1> $ST::{foo} = [1,2,3] 

    DB<2> *ST::bar = [1,2,3] 

    DB<3> x @ST::foo 
Cannot convert a reference to ARRAY to typeglob at (eval 7)[/usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl:646] line 2. 
at (eval 7)[/usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl:646] line 2 
    eval '([email protected], $!, $^E, $,, $/, $\\, $^W) = @saved;package main; $^D = $^D | $DB::db_stop; 
    @ST::foo; 

;' called at /usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl line 646 
    DB::eval called at /usr/local/perl/blead-debug/lib/5.15.0/perl5db.pl line 3442 
    DB::DB called at -e line 1 
    DB<4> x @ST::bar 
0 1 
1 2 
2 3 
    DB<5> x \%ST:: 
0 HASH(0x1d55810) 
    'bar' => *ST::bar 
    'foo' => ARRAY(0x1923e30) 
     0 1 
     1 2 
     2 3 
Các vấn đề liên quan