2013-06-13 13 views

答えて

4

Perlmodで覆われています。

::は、実際にはの名前空間です。初期のPerlでは、名前空間のこの考え方が成り立た取っ前に、あなたのプログラムの中で起こって変数名の衝突を持つことができます:

ここに私のプログラムがあります:

#! /usr/bin/env perl 

#use strict; 
use warnings; 
use feature qw(say); 

require "test2.pl"; 

$foo = "bar"; 

futz_with_foo(); 

say $foo; 

私はバー$fooを設定し、決してそれに触れました。 barを印刷しなければならないしかし、私は私のプログラムを実行すると、私が取得:test2.pl

$ ./test.pl 
WOO WOO! I MESSED WITH FOO! 

を、私は持っている:

sub futz_with_foo { 
    $foo = "WOO WOO! I MESSED WITH FOO!" 
} 
1; 

何が起こったことは、両方のプログラムが同じ変数$fooを使用していることです。この問題を回避するために、Perlはモジュールに独自の名前空間を持たせることができます。元の構文は一重引用符ですが、Perl 4の::(正しく覚えていれば)に変更されました。引き続き一重引用符を使用できます。名前空間はpackageで宣言します。

これを理解する最善の方法は、実際の動作を確認することです。次のことを試してみてください。

これを実行する
#! /usr/bin/env perl 

use strict; 
use warnings; 
use feature qw(say); 

our $foo = 'This is the value of $foo'; 

say '$foo: ' . $foo; 
say '$main::foo: ' . $main::foo; 
say "\$main'foo: " . $main'foo;; 

say "\nSwitching to package Bar"; 
package Bar; 

our $foo = 'This is in package Bar'; 

say '$foo: ' . $foo; 
say '$Bar::foo: ' . $Bar::foo; 

say "\nSwitching to package main again"; 
package main; 

say '$foo: ' . $foo; 

、私が手:デフォルトで

$foo: This is the value of $foo 
$main::foo: This is the value of $foo 
$main'foo: This is the value of $foo 

Switching to package Bar 
$foo: This is in package Bar 
$Bar::foo: This is in package Bar 

Switching to package main again 
$foo: This is in package Bar 

を、あなたのプログラムは、メイン名前空間に出発する。ところで、あなたはour $fooといい、my $fooではないことに気づくでしょう。これは、ourが、パッケージの変数が格納されているPerlシンボルテーブルに変数を格納するためです。 myはレキシカルスコープの宣言であり、現在は優先されています。 myで宣言された変数は、宣言されたスコープ内にのみ存在し、そのファイルの外にあることはできません。

myで変数を宣言するのを忘れると、エラーメッセージが表示されます。デフォルトでは

Global symbol "$foo" requires explicit package name at ... 

、すべてのPerlの変数はパッケージ変数(つまり、彼らはPerlのシンボルテーブルにいる)です。 use strictプラグマを使用すると、パッケージ変数をourと宣言するか、変数の完全なパッケージ名を使用する必要があります。 myで変数を宣言することで(つまり、99の40/100%の時間)、strictを使用して、Perlを使用するときに変数を宣言するように強制します。

これが役に立ちます。

3

ダブルコロン演算子::は(異なる容器に同様の名前のメソッドを区別する)部材がフォームであることをパッケージ、モジュール、またはクラスとパッケージのメンバー、モジュール、またはクラスをプレフィックスするために使用されるセパレータであります。詳細はthis pageをご覧ください。

12

これらはパッケージセパレータです。私は実際のコードが$SomePackage::SomeHash{'SomeKey'}のようなものだと思う。この構文では、「パッケージ変数」、この場合はハッシュ、他のパッケージ、または完全修飾名にアクセスできます。あなたは、おそらくのようなものを見にもっと慣れている:

package SomePackage; 
our %SomeHash; 
$SomeHash{'SomeKey'} # do something with $SomePackage::SomeHash{'SomeKey'} here 

ユースケースは、出力を制御するために、これらのパッケージ変数を使用する、Data::Dumper言うように、いくつかのモジュールを設定されています。しかし...

use Data::Dumper; 
local $Data::Dumper::Sortkeys = 1; 
print Dumper { c => 3, a => 1, b => 2 }; 

このタイプの使用法は、通常、オブジェクト指向スタイルを使用することによって回避されます。

関連項目:有名なのはMJDの記事「スコープへの対処」:http://perl.plover.com/FAQs/Namespaces.html

+0

あまりにもわかりにくく、実際にはお勧めしません...同じ目的のために、2つのコロン文字(::)の代わりに1つの引用符( ')を使用することもできます。 (Acme :: Do not libraryなどのものが生成されます)。 – runrig

+0

@runrig、私はそれについて言及しましたが、非常に非難されたIIRCです。それを使用しないでください。 '::'はThe Way(TM)です。 –

2

それは自分自身では何もありません。 SomePackage::SomeHashは全体として識別子である。 $someVariable::QUERY{'someString'}は、ハッシュ%someVariable::QUERYのハッシュ要素someStringを指します。ハッシュ%someVariable::QUERYは、パッケージsomeVariableのハッシュ%QUERYのフルネームです。