无论如何要告诉perl脚本是否通过do运行?

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

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

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

#config.pl
my $runViaDoFlag; 

$runViaDoFlag=$0=~/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基本的使用说明。

解决方案:

  • 测试 $0主脚本名称
  • 在主脚本中定义自定义包变量并由配置脚本检查
  • 只需在配置中添加注释,指导用户如何使用它。

这些工作,但是有没有办法知道脚本是否通过内置变量/子执行执行?

回答

我会提供设计上的更改:将该配置放在一个普通模块中,然后您可以在其中测试它是否已被(从) 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语句是好的。)

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

如果该配置代码也需要能够运行,如问题所示,那么有一个单独的可执行文件来加载此模块并运行需要运行的内容。


至于所述的问题,标题和问题的(明显)任务略有不同,但都可以通过使用调用者 EXPR来处理。不过,它不会是一个干净的小“内置”调用。

关于事情做的目的是可以使用的是

do' ./stat.pl'在很大程度上就像

eval `cat stat.pl`;

除了那个 ...

stat.pl早先在文档中介绍过,只是为了表示do在文件上调用。)

然后caller(0)将提供明确的提示(参见文档)。它返回

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

在要求, 的调用中do './config.pl',除了main(package) 和正确的文件名之外,caller(0)inconfig.pl还返回:

  • (eval) 为了 $subroutine

  • ./config.pl 为了 $evaltext

  • 1 为了 $is_require

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

但是,我不会推荐这种复杂的分析,而不仅仅是使用包,这也更加灵活。


以上是无论如何要告诉perl脚本是否通过do运行?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>