Perl类变量用法

时间:2010-03-04 21:54:45

标签: perl

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

我们有一个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();

假设launch()是dll公开的方法。但是由于{MY_DLL}指向一个引用,Perl抱怨这是可以理解的。语法是什么?

2)我是否需要在DESTROY中专门undef?即使我没有特别undef它,Perl会自动清理吗?

2 个答案:

答案 0 :(得分:9)

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的“Destructors”部分。

答案 1 :(得分:2)

无需存储对$my_dll的引用,Win32::OLE本身是sub my_dll { $_[0]->{MY_DLL} } 返回的引用。

为它编写一个访问器将使语法更加甜美,并允许您更改类的内部,而无需更改使用它的代码:

$object->my_dll->launch;

随后:

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

或者,如果在评论中注明@rjh,则不希望公开dll句柄,

$object->dll_launch;

并使用

Win32::OLE->new

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

  

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