Perl类变量的用法

问题描述:

我想了解如何在Perl OO中使用实例变量 - 更具体地说是与外部资源结合使用。让我解释一下:Perl类变量的用法

我们有一个DLL公开了一些我想通过Perl API公开的功能。我使用Win32::OLE来访问这个DLL。所以我的构造很简单:

package MY_CLASS; 
use Win32::OLE; 

sub new 
{ 
    my ($class) = @_; 

    # instantiate the dll control 
    my $my_dll = Win32::OLE->new("MY_DLL.Control"); 

    my $self = { 
     MY_DLL => \$my_dll, 
    }; 

    bless $self, $class or die "Can't bless $!"; 
    return $self; 
} 

sub DESTROY 
{ 
    my ($self) = shift; 
    undef $sef->{MY_DLL}; 
} 

正如你所看到的,我分配实例变量MY_DLL引用$my_dll。我有几个问题:

1)如何调用实例变量,因为它指向一个引用。因此,换句话说,我怎么能调用的dll的实例方法是这样的:

my $dll_class = new MY_CLASS; 
$dll_class->{MY_DLL}->launch(); 

假设推出()是由DLL暴露的方法。但是因为{MY_DLL}指向一个引用,所以Perl抱怨这是可以理解的。什么是语法?

2)我需要在DESTROY中专门设置undef吗?那就是Perl会自动清理,即使我没有专门的undef呢?

+3

你的'DESTROY'方法中的输入错误让我问标准问题:你用'use strict'和'use warnings'运行吗? – FMc 2010-03-04 22:26:04

+0

是的,Perl会自动收集$ self - > {MY_DLL}。 – jrockway 2010-03-04 23:02:55

1)取消引用调用前参考:

${$dll_class->{MY_DLL}}->launch(); 

使用\$,你正在服用的标参考。 ${...}是标量de参考运算符。

我不确定为什么你需要在所有使用到的基准的基准 - 你可以简单地MY_DLL设置为$my_dll,因为它已经是一个参考:

# ... 
my $self = { 
    MY_DLL => $my_dll, # note, the \ is no longer in front of $my_dll 
}; 
# ... 

,然后你可以用它打电话你的原始语法:

$dll_class->{MY_DLL}->launch(); 

2)Perl会自动清除任何没有引用指向它的东西。当你的物体被毁坏时,\$my_dll将不再有它的引用,因此也不会$my_dll,所以它会被自动销毁。

一般而言,如果您有指向自己的递归数据结构,您只需要担心。在这些情况下,您使用DESTROY来手动中断链接;在你的情况下,你不需要明确地设置undef的句柄。

有关参考文献的更多信息,请参阅perlref。有关垃圾收集,DESTROY方法和循环引用的信息,请参见perlobj的“Destructor”部分。

+0

感谢您的详细解释。 – John 2010-03-04 22:19:32

没有必要存储对$my_dll的引用,该引用本身是由Win32::OLE返回的引用。

编写一个访问它使得语法更甜,并允许您更改类的内部不改变使用它的代码:

sub my_dll { $_[0]->{MY_DLL} } 

后来:

$object->my_dll->launch; 

,或者,如果,因为@rjh在评论中注意到,你不想公开dll句柄,

sub dll_launch { 
    my $self = shift; 
    $self->{MY_DLL}->launch(); 
    return; 
} 

,并使用

$object->dll_launch; 

此外,注意从Win32::OLE以下:

请注意在Win32::OLE->new方法指定的析构函数。它确保即使Perl程序死亡,Excel也能正常关闭。否则,如果您的应用程序在打开Excel的OLE实例后死亡,则可能存在进程泄漏。模块用户有责任确保所有的OLE对象都被正确清理!

+0

一般来说很好的建议,但是如果这个模块委托给DLL,DLL句柄应该保持私有并且通过公共Perl方法进行封装。 – rjh 2010-03-04 22:27:31

+0

...除非它是私人的,否则还有其他方式来处理它。 :) – 2010-03-04 22:54:50

+0

你的意思是在包内声明'my $ dll'? – rjh 2010-03-05 00:51:52