代码之家  ›  专栏  ›  技术社区  ›  FMc TLP

当设置Perl代码作为脚本或模块运行时,uu package_uuuuu的原因是什么?

  •  4
  • FMc TLP  · 技术社区  · 15 年前

    在这 earlier Stackoverflow question 特别是 brian d foy's "How a Script Becomes a Module" 我已经阅读了如何设置代码,以便它可以作为脚本或模块运行,使用这种技术:

    package SomeModule;
    
    __PACKAGE__->run(@ARGV) unless caller();
    
    sub run {
        # Do stuff here if you are running the file as
        # a script rather than a module.
    }
    

    目的是什么 __PACKAGE__ 在这个设置中?为什么不直接这么做?

    run(@ARGV) unless caller();
    
    1 回复  |  直到 14 年前
        1
  •  14
  •   Chas. Owens    15 年前

    如果你说 __PACKAGE__->run(@ARGV) 然后 run 可以在继承自的类中定义,也可以允许类从此类继承。只要你说 run(@ARGV) 您缺少课程信息。这只在您进行OO风格的编程时才重要。

    将以下内容放入名为 Foo.pm 然后说 perl Foo.pm 1 2 3

    package Foo;
    
    use strict;
    use warnings;
    
    __PACKAGE__->main(@ARGV) unless caller;
    
    sub main {
        my $class = shift;
        my $obj   = $class->new(@ARGV);
        print $obj->to_string, "\n";
    }
    
    sub new {
        my $class = shift;
        return bless [@_], $class;
    }
    
    sub to_string {
        my $self = shift;
        return "args: " . join ", ", map { "[$_]" } @$self;
    }
    
    1;
    

    现在把下面的内容放进去 Bar.pm perl Bar.pm a b c .

    package Bar;
    
    use strict;
    use warnings;
    
    use base 'Foo';
    
    __PACKAGE__->main(@ARGV) unless caller;
    
    sub to_string {
        my $self = shift;
        return "args: " . join ", ", map { "<$_>" } @$self;
    }
    
    1;
    

    现在让我们看看如果你不使用 __PACKAGE__ 在这种环境下。使代码的第一部分 PM 看起来像这样:

    main(@ARGV) unless caller;
    
    sub main {
        my $obj = Foo->new(@ARGV);
        print $obj->to_string, "\n";
    }
    

    现在运行 perl foo.pm 1 2 3 . 一切都应该看起来正常。现在尝试运行 Perl巴.pm a b c . 我们仍然得到输出,但这不是我们期望的输出。如果我们移除 包装袋 PM ?好吧,我们得到错误: Undefined subroutine &Bar::main called at Bar.pm line 8. 这是因为没有 main 模块中的函数,我们不使用类调用它,因此它不会在 Foo 再打包。