2016-03-05 130 views
-4

当调用perl构造函数时,类引用被传递给新函数,但构造函数不初始化类变量,如java或C++ does.inf它创建一个新的哈希和祝福它在类的引用并返回它。这造成了子例程不能直接引用它们必须使用传递的隐式引用的变量的问题。为什么perl构造函数不初始化包(class)变量

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

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

明确包装方法有可能使用参考自使用VAR1,VAR2,VAR3 这是不是包变量,但只有哈希的对象。

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

+2

这就是它在Perl中的样子。包范围变量就像Java中的类变量。 - Perl发行版中有几个OO教程。阅读这些初学者。 – laune

+3

示例代码已损坏。它具有不平衡的大括号,并有'new'方法调用'new'方法。如果代码更清晰,理解这个问题可能会更容易。 – mob

+0

yeah纠正了!!!谢谢 –

回答

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 
+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(); 

这是一个基于Perl5对Object的初始支持,在Perl中处理OO的较老方法。如果您更熟悉其他对象系统,则可能需要查看Perl的Moose库,这些库提供了更多您可能习惯的内容。

HTH,

凯尔

+0

感谢您的解释。Static这个词几乎消除了所有的疑惑。调用包中的 可以在这些静态字段上使用setter来动态设置值。我们如何在perl中创建实例变量? –

+0

嗨@RahulKumar在我的例子中,'prop1'和'prop2'是实例变量。你熟悉Javascript吗?对象在JS和Perl中具有非常相似的语义。 '$ self - > {prop1}'_is_一个成员变量。你可以随时'创建'新的(再次就像在JS中),通过分配'$ self - > {prop99}' –

+0

Hi @kyle,我明白prop1和prop2是你创建的散列的有效键进入参考,他们可以被认为是实例变量。再次访问这些我必须使用$ self在函数中传递。我想问的是有没有一种方法可以将包变量声明为实例变量?或包变量总是静态的? –