我应该如何处理不再在Perl中使用的对象? [英] What should I do with an object that should no longer be used in Perl?

查看:97
本文介绍了我应该如何处理不再在Perl中使用的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个链接到外部资源的类.其中一种方法是删除方法,它会破坏外部资源.不应在该对象上进行进一步的方法调用.我正在考虑设置一个标志,如果设置了标志,则会在所有方法中死亡,但是有没有更好,更简便的方法呢?可能涉及到DESTROY吗?

I am writing a class that is linked to an external resource. One of the methods is a delete method that destroys the external resource. No further method calls should be made on that object. I was thinking of setting a flag and die'ing inside of all of the methods if the flag is set, but is there a better, easier way? Something involving DESTROY maybe?

到目前为止,我真的很喜欢Axeman的建议,但是使用AUTOLOAD是因为我懒于重新创建所有方法:

So far, I am really liking Axeman's suggestion, but using AUTOLOAD because I am too lazy to recreate all of the methods:

#!/usr/bin/perl

use strict;
use warnings;

my $er = ExternalResource->new;

$er->meth1;
$er->meth2;

$er->delete;

$er->meth1;
$er->meth2;

$er->undelete;

$er->meth1;
$er->meth2;

$er->delete;

$er->meth1;
$er->meth2;
$er->meth3;

package ExternalResource;

use strict;
use warnings;

sub new {
    my $class = shift;
    return bless {}, $class;
}

sub meth1 {
    my $self = shift;
    print "in meth1\n";
}

sub meth2 {
    my $self = shift;
    print "in meth2\n";
}

sub delete {
    my $self = shift;
    $self->{orig_class} = ref $self;
    return bless $self, "ExternalResource::Dead";
}

package ExternalResource::Dead;

use strict;
use Carp;

our $AUTOLOAD;
BEGIN {
our %methods = map { $_ => 1 } qw/meth1 meth2 delete new/;
}
our %methods;

sub undelete {
    my $self = shift;
    #do whatever needs to be done to undelete resource
    return bless $self, $self->{orig_class};
}

sub AUTOLOAD {
    my $meth = (split /::/, $AUTOLOAD)[-1];
    croak "$meth is not a method for this object"
        unless $methods{$meth};
    carp "can't call $meth on object because it has been deleted";
    return 0;
}

推荐答案

仅考虑对象处于无效状态是否存在问题.如果用户坚持使用它,这不是他们的问题吗?

Is there a problem with simply considering the object in an invalid state. If the users hang on to it, isn't that their problem?

以下是一些注意事项:

  • 您是否已经决定是否值得死?

  • Have you already decided whether it's worth dying over?

机会是,如果您具有足够封装的功能,则您确实不希望用户通过您的代码进行解析.为此,您可能不希望使用我所说的Go-ahead-let-it-fail模式. 'Can't call method "do_your_stuff" on an undefined value'可能无法很好地用于封装目的.除非您告诉他们嘿,您删除了该对象!

Chances are that if you have a function that is encapsulated enough, you really don't want to have the users parse through your code. For that purpose, you probably wouldn't like to use what I call the Go-ahead-and-let-it-fail pattern. 'Can't call method "do_your_stuff" on an undefined value' probably won't work as well for encapsulation purposes. Unless you tell them "Hey you deleted the object!

以下是一些建议:

  • 您可以将对象 lessbless 放到一个类中,该类的唯一工作就是指示无效状态.它具有相同的基本形式,但表中的所有符号都指向一个子句,该子句仅表示对不起,我已经被关闭了(您将我关闭了,记得吗?)."

  • You could rebless the object into a class whose only job is to indicate an invalid state. It has the same basic form, but all symbols in the table point to a sub that just says "Sorry can't do it, I've been shut down (You shut me down, remember?)."

您可以在删除操作中取消对$_[0]的定义.然后他们从他们的代码行中得到了一个不错的'Can't call method "read_from_thing" on an undefined value',前提是他们没有经过精心的装饰或委派过程.但是,正如混乱所指出的那样,这并不能消除一个以上的引用(正如我已经通过下面的示例代码进行了展示).

You could undef $_[0] in the delete. Then they get a nice 'Can't call method "read_from_thing" on an undefined value' from a line in their code--provided that they aren't going through an elaborate decorating or delegation process. But as pointed out by chaos, this doesn't clear up more than one reference (as I've adapted by example code below to show).

一些概念证明材料:

use feature 'say';

package A;

sub speak { say 'Meow!'; }

sub done { undef $_[0]; }

package B;

sub new { return bless {}, shift; }

sub speak { say 'Ruff!' }

sub done { bless shift, 'A'; }

package main;

my $a = B->new();
my $b = $a;

$a->speak(); # Ruff!
$b->speak(); # Ruff!
$a->done();
$a->speak(); # Meow!
$b->speak(); # Meow! <- $b made the switch
$a->done();
$b->speak(); # Meow!
$a->speak(); # Can't call method "speak" on an undefined value at - line 28

这篇关于我应该如何处理不再在Perl中使用的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆