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

时间:2016-03-05 17:11:07

标签: perl class-variables

当调用perl构造函数时,类引用被传递给新函数,但是构造函数不会初始化像java或c ++这样的类变量。相反,它创建了一个新的Hash并在类引用中保存它并返回它。这创建了子程序不能直接引用它们必须使用传递的隐式引用的变量的问题。

以下代码将突出显示此问题: -

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} 
       }

显然,package方法必须使用引用self来使用var1,var2,var3 这不是包变量,而只是哈希的对象。

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

2 个答案:

答案 0 :(得分: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对Objects的初始支持。如果您对其他对象系统更熟悉,可能需要查看Perl的Moose库,这些库提供了您可能习惯的更多内容。

HTH,

凯尔

答案 1 :(得分:2)

使用包变量的规范方法是使用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