无论如何要通过 do 判断 perl 脚本是否为 运行?

Anyway to tell if perl script is run via do?

我有一个从主脚本加载的小脚本配置文件。

#main.pl
package MYPACKAGE;
our $isMaster=1;

package main;
my config=do "./config.pl"

#config.pl
my $runViaDoFlag; 

$runViaDoFlag=[=12=]=~/main\.pl/;                  #Test if main.pl is the executing script
$runViaDoFlag=defined $MYPACKAGE::isMaster;    #Test custom package variable
                                               #Is there a 'built-in' way to do this?

die "Need to run from main script! " unless $runViaDoFlag;

{
    options={
        option1=>"some value",
        option2=>"some value",
    },
    mySub=>sub { 
               # do interesting things here
           }
}

在更复杂的配置文件中,config.pl 脚本只能由 do 执行的情况可能不会那么明显。因此,我想包括一个 die 和基本使用说明。

解决方案:

这些工作,但是有什么方法可以知道脚本是否通过内置的 do 执行?variable/subs?

我会提供一个设计更改:在普通模块中进行配置,然后您可以在其中测试它是否被 main:: 命名空间加载(从)。那么就不需要任何带有控制变量等的杂技

一种方法

use warnings;
use strict;
use feature 'say';

use FindBin qw($RealBin);
use lib $RealBin;          # so to be able to 'use' from current directory

use ConfigPackage qw(load_config);

my $config = load_config();
# ...

ConfigPackage.pm(在同一目录)

package ConfigPackage;

use warnings;
use strict;
use feature 'say';
use Carp;

use Exporter qw();                 # want our own import
our @EXPORT_OK = qw(load_config);

sub import { 
    #say "Loaded by: ", (caller)[0];
    croak "Must only be loaded from 'main::'"
        if not ( (caller)[0] eq 'main' );

    # Now switch to Exporter::import to export symbols as needed
    goto &Exporter::import;
}

sub load_config {
    # ...
    return 'Some config-related data structure';
}

1;

(注意这个使用goto没问题。)

这当然只是草图;根据需要进行调整、进一步发展和修改。如果这是从 main:: 以外的包中加载的,因此它失败了,那么它发生在编译阶段,因为那是调用 import 的时候。我认为这是一件好事。

如果该配置代码也需要能够 运行,正如问题可能表明的那样,那么有一个单独的可执行文件来加载这个模块和 运行 需要的是 运行.


至于所陈述的问题,标题和问题的(明显的)追求略有不同,但都可以使用 caller EXPR 来处理。不过,这不会是一个干净的小“built-in”调用。

关于 do 的目的是

do './stat.pl' is largely like

eval `cat stat.pl`;

except that ...

stat.pl 之前在文档中介绍过,只是表示对文件调用了 do。)

然后 caller(0) 将提供明确的提示(请参阅文档)。它returns

my ($package, $filename, $line, $subroutine, $hasargs,
    $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
= caller($i);

在请求中,do './config.pl',除了main(包)和正确的文件名外,config.pl中的caller(0)也returns :

  • (eval) 对于 $subroutine

  • ./config.pl 对于 $evaltext

  • 1 对于 $is_require

总而言之,这足以决定调用是否按要求进行。

但是,我不推荐这种涉及分析的方式,直接用一个包,也是灵活无比的。