为什么perl构造函数不初始化包(class)变量

why does perl constructor not initialize the package(class) variables

当调用 perl 构造函数时,class 引用被传递给新函数,但构造函数不会初始化 class 变量,例如它创建的 java 或 c++ does.Instead一个新的 Hash 并在 class 引用和 returns it.This 中对其进行祝福会产生子例程无法直接引用变量的问题,它们必须使用传递的隐式引用。

下面的代码将突出问题:-

package foo;
use strict;
my $var1;
my $var2;
my $var3;

sub new {
    my $class = shift;
    my $self  = {
        var1 => shift,
        var2 => shift,
        var3 => shift
      };

    bless $self, $class;
    return $self;

      }

sub method {

        my $self = shift;
        print(
            "variable value are $self->{var1},$self->{var2},$self->{var3}";
       #how to directly refer to var1 declared above? instead of self->{var1} 
       }

很明显,包方法必须使用引用 self 才能使用 var1、var2、var3 这不是包变量,而只是散列的对象。

1:-这意味着在 perl 中没有办法初始化包变量?? 2:-如果我用某种方法明确地初始化它们,它们是对所有对象都有一个副本还是每个对象都有不同的副本

在 Perl 中,包变量,例如:文件顶部的 my $var1,不是实例变量。它们对应于 Java 或 C# 等语言中的静态变量。在 Perl 中,通常使用 $self 而其他语言使用 this。某些语言,如 Java,允许您在引用成员变量时省略 this 的使用。有些,如 JavaScript 和 Perl 则没有。

如果您询问如何初始化静态变量,您当然可以通过在创建它们时分配给它们来做到这一点。

package foo;
use strict;
use warnings;
my $created_at = localtime();

sub created_at {
  return $created_at;
}

sub new {
  my($pkg,$p1,$p2) = @_;
  my $self = {
    prop1 => $p1,
    prop2 => $p2
  };
  return bless $self, $pkg;
}

# you can create accessors, think of these as getters and setters, if you pass a value it is set
sub prop1 { my($self,$v) = @_; $self->{prop1} = $v if @_>1; return $self->{prop1}; } 
sub prop2 { my($self,$v) = @_; $self->{prop2} = $v if @_>1; return $self->{prop2}; }

sub method {
  my($self) = @_;
  print "prop1=",$self->{prop1},"; prop2=",$self->{prop2},"\n";
}

package main;
use strict;
use warnings;

print "created_at = ",foo->created_at,"\n";

my $f = foo->new("banana","apple");

print "f->created_at = ", $f->created_at,"\n";
$f->method();
$f->prop1('orange');
$f->method();

这是在 Perl 中处理 OO 的旧方法,基于 Perl5 对对象的初始支持。如果您更熟悉其他对象系统,您可能想看看 Perl 的 Moose 库,它提供了更多您可能习惯使用的内容。

HTH,

凯尔

使用包变量的规范方法是用our声明它们。在包外,您可以通过包限定变量名来引用它们。

package foo;
our ($var1, $var2, $var3) = (5, 42, "bar");
sub new { bless { var4 => $_[1] }, $_[0] }
...
1;


package main;
use foo;
$obj = foo->new(19);   # instance of foo
print "Instance variable is $obj->{var4}\n";    # 19
print "Package variable is $foo::var1\n";       #  5