4

Perl は初めてで、古い Perl Web サイトを更新しています。すべての.plファイルの先頭に次の行があるようです。

do "func.inc";

そこで、このファイルを使用して、グローバルに使用するサブルーチンにタグを付けることができると考えました。

株式会社ファンク

#!/usr/bin/perl
sub foobar
{
    return "Hello world";
}

index.pl

#!/usr/bin/perl
do "func.inc";
print "Content-type: text/html\n\n";
print foobar();

ただし、次のエラーが表示されます。

Undefined subroutine &main::foobar called at /path/to/index.pl line 4.

両方のファイルは同じディレクトリにありfunc.inc、Web サイト全体で使用されているサブのトーンが既に存在します。ただし、スクリプトは Linux 運用環境では機能しますが、Windows 7 開発環境では機能しません (私は ActivePerl を使用しています)。

アップデート:

ファイルが含まれていないようです。ファイルが絶対パスを使用して含まれている場合、サブは機能します...

do "C:/path/to/func.inc";

...そのため、ローカルの開発環境では相対パスが機能しないように見えますが、運用環境では機能します。しかし、私の開発マシンの絶対パスはライブサーバーでは機能しないため、これは私にとっては良くありません。

doWindows 7 開発マシンで相対パスを使用して作業するにはどうすればよいですか?

更新 2:

Perl-Tスイッチを使用していました。残念ながら、これは「。」を削除します。@INC からのパスなので、 に相対パスを使用できなくなりますdo。このスイッチを削除したところ、古いコードが機能するようになりました。これが良い習慣ではないことは承知していますが、残念ながら古いコードで作業しているため、仕方がないようです。

4

5 に答える 5

6

読み取りに関するperlfunc ドキュメントdo

  • do EXPR
    の値をEXPRファイル名として使用し、ファイルの内容を Perl スクリプトとして実行します。

    do 'stat.pl';
    

    のようです

    eval `cat stat.pl`;
    

    ただし、より効率的で簡潔であり、エラー メッセージの現在のファイル名を追跡し、ディレクトリを検索し、ファイルが見つかった場合は@INC更新します。%INC

したがって、これらすべての動作を確認するには、C:\Cygwin\tmp\mylib\func.inc次のように言います

sub hello {
  print "Hello, world!\n";
}

1;

そして、次のプログラムでそれを利用します。

#!/usr/bin/perl

use warnings;
use strict;

# your code may have unshift @INC, ...
use lib "C:/Cygwin/tmp/mylib";

my $func = "func.inc";

do $func;

# Now we can just call it. Note that with strict subs enabled,
# we have to use parentheses. We could also predeclare with
# use subs qw/ hello /; 
hello();

# do places func.inc's location in %INC
if ($INC{$func}) {
  print "$0: $func found at $INC{$func}\n";
}
else {
  die "$0: $func missing from %INC!";
}

その出力は

こんにちは世界!
./prog: C:/Cygwin/tmp/mylib/func.inc にある func.inc

あなたが観察したように、ドキュメンテーションで説明doされている水晶の階段が常にあるとは限りません:do

doファイルを読み込めない場合は、エラーに戻り設定undef$!ます。do がファイルを読み取ることはできてもコンパイルできない場合は、 を返しundef、 にエラー メッセージを設定します$@。ファイルが正常にコンパイルされた場合do、最後に評価された式の値を返します。

これらすべてのケースをチェックするには、単に使用することはできませんdo "func.inc"が、

unless (defined do $func) {
  my $error = $! || $@;
  die "$0: do $func: $error";
}

以下、ケースごとの解説です。

doファイルを読み取れません

に名前を変更func.incnope.incてプログラムを再実行すると、

./prog: do func.inc: No such file or directory at ./prog line 12.

doファイルを読み取ることはできますが、コンパイルすることはできません

名前を変更nope.incfunc.incて閉じ中括弧を削除し、次のhelloようにします

sub hello {
  print "Hello, world!\n";

1;

今プログラムを実行すると、

./prog: do func.inc: C:/Cygwin/tmp/mylib/func.inc 行 4、行末に右中括弧または角括弧がありません
C:/Cygwin/tmp/mylib/func.inc 行 4、EOF の構文エラー

doファイルを読み取ってコンパイルできますが、真の値は返されません。

1;の末尾の を削除しfunc.incて作成します

sub hello {
  print "Hello, world!\n";
}

今、出力は

./prog: do func.inc: ./prog 13 行目。

したがって、戻り値がなければ、成功は失敗に似ています。の結果をチェックするコードを複雑にすることもできますdoが、より適切な選択は、Perl ライブラリとモジュールの最後で常に true 値を返すことです。

汚染チェック ( -T) が有効になっていても、プログラムは正しく実行されることに注意してください。試してみてください!汚染モードと@INCperlsecを必ず読んでください。

于 2010-01-10T12:54:53.180 に答える
3

サブルーチンは、他のサブルーチンを使用するのと同じ方法で使用します。をロードしてもかまいませんdo。ただし、そのために使用するべきではありませんdo。他のファイルからのサブルーチンのロードの詳細な説明については、中級Perlの「パッケージ」の章を確認してください。つまり、代わりにrequireを使用してください。

doのドキュメントを参照してください。Perlがライブラリを検索するディレクトリの1つにfunc.inc ( plは「perllibrary」であるためfunc.plを呼び出すこともできます)が必要です。これは、 index.plがあるディレクトリとは異なる場合があります。func.incをどこかに置くか、そのディレクトリをに追加します。また、ファイルを読み込めなくても死ぬことはないので、失敗したことはわかりません。そのため、ライブラリのロードには使用しないでください。:)@INC@INCdodo

于 2010-01-10T11:34:29.237 に答える
2

パスが正しいことを確認して、次を使用します。


#!/usr/bin/perl 
require("func.inc");
print "Content-type: text/html\n\n"; 
print foobar(); 
于 2010-01-10T11:56:25.783 に答える
1

最初に、ファイルが実際にロードされたかどうかを確認します。ドキュメントにdo%INCは、ファイルが見つかった場合に更新されることが記載されています。ドキュメントにも詳細があります。

于 2010-01-10T11:34:06.477 に答える
0

正しいパスにfunc.incがあることを確認してください。

do "func.inc" 

func.incがperlスクリプトと同じパスにあると言っていることを意味します。正しいパスを確認してから、これを実行してください

do "/path/func.inc"
于 2010-01-10T11:37:20.050 に答える