2011-07-06 13 views
8

Perl'de, aşağıdaki iki yapı arasında herhangi bir fark vardır:Perl'de, doğrudan glob takma ve stash yoluyla takma arasındaki fark var mıdır?

*main::foo = *main::bar 

Aynı işleve sahip gibi görünüyorlar (*main::foo içinde *main::foo'te tanımlanmış olanların tümüyle aynı şekilde)), ama sadece bu denkliğin daima geçerli olup olmadığını merak ediyorum.

+3

Bunu ne getirdiğini merak ediyorum. :) –

+1

Birincisi, katı 'subs' veya sıkı etkinleştirildiğinde bir hataya neden olur, ikinciye izin verilir. – MkV

+1

Birkaç metot ismini bir araya getirmek için bir döngü yazıyordum ve neden her zaman neden yazdığımı merak etmeye başladım. * {'some :: pkg'. $ new} = * {'bazı :: pkg'. $ eski} '$ bazı olduğunda :: pkg :: {$ new} = $ bazı :: pkg :: {$ eski } 'de iyi çalışırdı. Sezgisel olarak aynı görünürler, ancak kopyalar/aşırı yüklenmeler/diğer büyü gibi şeyler, kopyasını farklı bir şekilde ele alırlarsa, ya bir hata ya da amaçlanmış bir davranış olarak “ilginç” sonuçlara sahip olabilirler. –

cevap

9
Belki

aradığınız farkın türden değil, ama *main::foo ve $main::{foo} arasında iki büyük farklılıklar vardır; Birincisi, küreyi derme zamanında kürsüye bakar, gerekirse onu yaratır, ikincisi ise çalışma zamanında haznede küreyi arar ve onu yaratmaz.

Bu, saklanmakta olan başka bir şey için bir fark yaratabilir ve kesinlikle bir used only once uyarısı alıp almayacağınızı etkileyebilir.

+0

Benim gibi Perl ezoterik olmayan insanlar için: [Stashes ve Globs] (http://www.perlmonks.org/?node=perlguts#Stashes_and_Globs): "* Bir stash tüm farklı nesneleri içeren bir karma olduğunu Bir paketin içinde yer alır.Stazın her bir anahtarı bir sembol adıdır (aynı ada sahip tüm farklı nesne türleri tarafından paylaşılır) ve hash tablosundaki her bir değer bir GV'dir (Glob Değeri). dönüş bu ismin çeşitli nesnelerine referanslar içerir * "... Perl yolculuğu asla bitmez! –

+0

@DavidTonhofer özellikle bu tam olarak doğru olmadığından; Bazı durumlarda, sakının GV olmayan değerler olabilir. – ysth

3

Aşağıdaki komut dosyası:

#!/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"; 

Çıkışlar:

Yani
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()'" 

*main::foo = *main::bar;$main::{foo} = $main::{bar}; aynı şeyi yapmazsa, ben pratik bir algılamaya nasıl bir kayıp am farkı. Bununla birlikte, bir sözdizimi perspektifinden, bir yöntemin diğerine göre daha kolay kullanıldığı durumlar olabilir. ... sembol tablosunda dolanmanın olağan uyarıları her zaman geçerlidir.

+0

Benim tahminim, herhangi bir farkın (eğer varsa) bazı ezoterik büyü veya aşırı önbellekleme algoritması içinde olacağıdır.sözdizimsel olarak kesinlikle farklılıklar vardır, "import" rutininde 'katı' refs''le eşleşmeyen glob atama kodunun, aramayı ayırma ve sembol tablo seviyesini düz olarak elle tutmanın biraz daha kısa (ve daha hızlı) olması, Bu, söz dizimi sözdizimini tercih etmeme neden olur, ancak önceden bilinen tam nitelikli bir adama yazarken (veya başka bir nedenden ötürü zaten bir zemini işlerken), sözdizimsel fark biraz katildir, bu nedenle soru :) –

+1

Kapağın altına bakma eğlenceli bir saptırmadır. İyi eski glob notasyonunun en açık olduğu durumlar olduğu halde, $ namespace :: {key} gösteriminin daha net olduğu başka durumlar da var. Belirli bir ihtiyaç için hangisi daha açıksa, bunu yapmanın yolu budur. :) Tabii ki, bir kişi sembol tablosunun içinden geçmenin bir alternatifi bulabilirse, tasarımdan yaklaşmayı önlemek için birçok neden vardır. – DavidO

3

$A::{foo} = $obj Eğer *A::foo = $obj yerler typeglob beklenen yuvaya $obj$obj tipine göre ise sembol masaya şey yerleştirmek için izin verdiği zulası erişme.

Örneğin

:

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