2009-09-20 5 views
14

私はいくつかのファイル名の定数を取り入れたたくさんのPerlファイルを持っています。私はCでヘッダファイルのようなものを別のファイルに定義したいと思います。これはPerlでこれを行う最も一般的な方法です。Perlで別のファイルに定数を定義する方法はありますか?

+2

この質問に非常に近い複製:http://stackoverflow.com/questions/193020/how-do-i-use-constants-from-a-perl-module – draegtun

答えて

16

PerlにはCヘッダファイルと同等のものはありません。グローバル定数を宣言して定義するには、defineプラグマを使用します。インターフェイスは分かりやすいようですが、私はこのモジュールの経験がありません。

一方、定数を定義し、useを使用してモジュールにインポートするモジュールを記述することができます。たとえば、次のようにあなたは、このモジュールを使用することができます

package MyConstants; 

use strict; use warnings; 

use Exporter qw(import); 
use Const::Fast; 

our @EXPORT = qw(); 
our @EXPORT_OK = qw($X $Y); 

const our $X => 'this is X'; 
const our $Y => 'this is Y'; 

__PACKAGE__; 
__END__ 

:あなたは完全修飾変数名(例えば$MyConstants::Y)を使用してOKであれば

#!/usr/bin/perl 

use strict; use warnings; 

use MyConstants qw($X); 

print "$X\n"; 
print "$MyConstants::Y\n"; 

を、あなたは全くExporterを必要としません。

また、エクスポートする変数が別の場所で変更できないようにしてください(Exporterの注意事項を参照してください)。

もちろん、constant.pmを使用して定数を定義することもできます。このような定数を使うほうが速いかもしれませんが、文字列でそれらを補間する必要がある場合は、扱いにくいです。

+3

Readonly :: Scalarは、Readonly :: XSがインストールされていればかなり高速です。ハッシュと配列はまだ遅いです。 –

+1

エクスポータdocs(http://perldoc.perl.org/Exporter.html)では、変数をエクスポートすることはできませんが、エクスポートすることをお勧めします。 –

+2

@Robert P、要求に応じて変数をエクスポートするIMOは合理的ですが、デフォルトで1つ(またはそれ以上!)をエクスポートするのは避けてください。上記の例では、$ Xを何度も何度も使用することを期待していて、どこでも '$ MyConstants :: X 'と入力しなければならないという無駄な繰り返しを避けたい場合、大きなメリットがあります。インポートされた変数のもう1つの例は、私が誤って '$ MyConstants :: x'を使用しようとした場合、' strict'生成されたエラーメッセージが私のエラーを警告するのではなく、 '$ X'をインポートして' x'は、エラーをキャッチして厳密に保存します。 – daotoad

-2

「require」または「use」を後で使用できるように、perlモジュールとして書き込む方法もあります。あなたはこのようなあなたのファイルを作成したい - それを.PM拡張(例えば、myFabulousPackage.pm)を得

package myFabulousPackage; 

$someSetting=45; 
$otherSetting='Fish'; 

1; 

を次に、あなたのperlスクリプトで、これはファイルをインクルードして、otherSetting $を参照します:

#!/usr/bin/perl 

use myFabulousPackage; 

print $myFabulousPackage::otherSetting; 

これはパッケージ/モジュールでできることを非常に簡単に示していますが、必要な場合は実装するのが最も簡単な方法です。同様に、サブパッケージもパッケージに入れて同様の方法で参照することができます。

+3

これは動作しません。 my(字句変数)で宣言された変数は '$ PackageName :: varname'でアクセスできません。この構文は、シンボルテーブル内の変数にのみアクセスします。変数をシンボルテーブルに入れる最も良い方法は、 'our'を使って変数を宣言することです。 – daotoad

+1

これは実際には機能しません。変数の 'my'宣言はそれらをレキシカルスコープにし、' .pm'ファイル内のコードにしか見えません。あなたはそれらを代わりに '私たち 'と宣言したいと思っています。また、モジュールファイルを常に '1;'で終了させることは良い考えです。何故なら、最後のステートメントが何らかの方法で偽の値に評価されると、モジュールはロードされないからです。 – arnsholt

+0

ええ - あなたは「私」について正しいです...それは私がオートパイロットにperlを書くことであり、私の例を二重にチェックするものではありません。編集しました。 –

7

通常、これはモジュール名の定数で行います。それを使用する次に

package MyPackage::Constants; 

our $DIR = "/home/chriss"; 
our $MAX_FILES = 5; 

1; 

、::

package MyPackage; 
use MyPackage::Constants; 

open(my $fh, ">", $MyPackage::Constants::DIR . "/file"); 

あなたがパッケージのすべての時間を参照するようにしたくなかった場合は、輸出を使用して、必要なすべてのシンボルに持って来ることができるような何か。

+3

新しい名前空間を作成するのではなく、MyPackageモジュール自体にMyPackage定数を定義してみませんか?また、定数をnamespace :: DIRとして参照すると、継承の利点が失われます。つまり、MyPackage :: Child :: ConstantsはMyPackage :: Constantsから継承できず、DIRの値をオーバーライドします。 namespace-> DIRがはるかに優れています。 – Ether

+1

これは説明のための単純な例です。つまり、すべてがオブジェクト指向ではありません:) –

+4

それは構成ではなく、定数のように見えます。 –

5

これは構成設定のように聞こえます。これは、さまざまなCPANモジュールの1つ、たとえばConfig::Anyで解析する設定ファイルに入れる方がよいでしょう。

設定はデータであり、IMOはあなたのコードに含まれてはいけません。

関連する問題