2011-07-06 7 views
8

、以下の2つの構築物の間の任意の差がこれまで存在する。Perlでは、ダイレクトグロブエイリアシングと隠蔽によるエイリアシングに違いはありますか? Perlで

*main::foo = *main::bar 

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

彼らは(で定義されたものに*main::fooのスロットの全てをエイリアシング同じ機能を有するように見えます*main::bar)、この同等性が常に成立するかどうかは疑問です。

+3

私はこのことをもたらしたのは不思議です。 :) –

+1

厳密な 'subs'またはstrictが有効な場合、前者はエラーを引き起こします。後者は許可されます。 – MkV

+1

私はいくつかのメソッド名を別名にするためのループを書いていて、なぜ{{厳密な 'refs'も書いていません。 '' some :: pkg '。$ new} = * {'some :: pkg'。$ old}' '$ some :: pkg :: {$ new} = $ some :: pkg :: {$ old } 'も同様に機能します。直感的にはそれらは同じように見えますが、バグや意図された動作のいずれかとしてコピーを別々に処理すると、結びつき/オーバーロード/その他の魔法のようなものが「面白い」結果をもたらす可能性があります。 –

答えて

9

そうでないかもしれない、あなたが探していたが、*main::foo$main::{foo}の間に2つの大きな違いがあるの違いのようなもの。前者はコンパイル時にstashのglobを検索し、必要に応じて作成します。後者は、実行時にstashのglobを検索し、作成しません。

これは、隠し場所を突き刺すことに何らかの差異をもたらす可能性があり、警告がused only onceの警告を受け取るかどうかに影響を与える可能性があります。

+0

Perlエソテリックスに属していない私のような人々のために:[Stashes and Globs](http://www.perlmonks.org/?node=perlguts#Stash_and_Globs): "* stashは異なるオブジェクトのすべてを含むハッシュですスラッシュの各キーはシンボル名(同じ名前を持つすべての異なるタイプのオブジェクトによって共有されます)であり、ハッシュテーブルの各値はGV(Glob Value)です。 turnはその名前のさまざまなオブジェクトへの参照を含んでいます* "... Perlの乗り物は決して終わりません! –

+0

@DavidTonhoferこれは特に正確ではないためです。場合によっては、隠しはGVではない値を持つことがあります。 – ysth

3

次のスクリプト:

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

出力:*main::foo = *main::bar;$main::{foo} = $main::{bar};と同じことをしない場合

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

だから、私は実用的に検出する方法として、途方に暮れてよ差。 ;)しかし、構文の観点からは、あるメソッドと別のメソッドを使い分ける方が簡単な場合があります。 ...シンボルテーブルの周りにぶつかることに関する通常の警告が常に適用されます。 $A::{foo} = $objとしてスタッシュへのアクセス

+0

私の推測では、もしあれば何らかの秘密の魔法や過激なキャッシングアルゴリズムに違いがあるということです。構文的には違いはありますが、globの割り当てと 'import 'ルーチンの'厳格な' refs''とのコードは、手で離れてシンボルテーブルのレベルを手動で移動するよりもかなり短く(速く)グロブ構文を好むようになりますが、事前に知られている完全修飾名に書き込むとき(または他の理由で隠しをすでに処理しているとき)、構文上の違いは少し曖昧です。したがって、疑問です。 –

+1

フードの下を見る楽しい転用です。私は、良い古いグロブ記法が最も明瞭である状況があると考えていますが、$ namespace :: {key}表記が明瞭である他の状況もあります。どちらが特定のニーズに対してより明確であるかは、それを行う方法です。 :)もちろん、人がシンボルテーブルを横切るための選択肢を見つけることができれば、いずれのアプローチも設計上避けなければならない多くの理由があります。 – DavidO

3

あなたは$obj種類に応じた型グロブの予想スロットに*A::foo = $obj場所$objながら、シンボルテーブルの上に何かを配置することができます。例えば

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 
関連する問題