在我目前的工作中,我正在构建一套perl脚本,这些脚本在很大程度上取决于对象。 (使用Perl的 bless() 在哈希上,尽可能接近OO)

现在,由于缺乏更好的方式,我公司的大多数程序员都不是很聪明。更糟糕的是,他们不喜欢阅读文档,似乎有一个问题理解他人的代码。牛仔编码是这里的游戏。每当他们遇到问题并尝试解决问题时,他们就会提出一个可怕的解决方案,实际上什么也没解决,通常会使情况变得更糟。

坦率地说,这导致我不信任用鸭子打字语言写的代码。例如,我看到他们太多问题没有因滥用对象而遇到明确的错误。例如,如果输入 A 有会员 foo, ,他们做类似的事情 instance->goo, ,他们不会立即看到问题。它将返回零/未定义的值,他们可能会浪费一个小时找到原因。然后最终更改其他内容,因为他们没有正确地识别原始问题。

因此,我正在集思广益,以保持脚本语言(其快速发展是一个优势),但是当对象无法正确使用时,给出明确的错误消息。我意识到,由于没有编译阶段或静态键入,因此必须在运行时出错。我对此很好,只要用户得到非常明确的通知,说“这个对象没有x”

作为我解决方案的一部分,我不希望他们在尝试使用它之前检查方法/变量是否存在。

即使我的工作在Perl中,我认为这可能是语言不可知论的。

有帮助吗?

解决方案

如果您有任何添加模块的镜头,请尝试 驼鹿. 。它几乎提供了您在现代编程环境中想要的所有功能,等等。它确实类型检查,出色的继承,具有内省功能,并具有 Moosex ::声明, ,是Perl类最好的接口之一。看一看:

use MooseX::Declare;

class BankAccount {
    has 'balance' => ( isa => 'Num', is => 'rw', default => 0 );

    method deposit (Num $amount) {
        $self->balance( $self->balance + $amount );
    }

    method withdraw (Num $amount) {
        my $current_balance = $self->balance();
        ( $current_balance >= $amount )
            || confess "Account overdrawn";
        $self->balance( $current_balance - $amount );
    }
}

class CheckingAccount extends BankAccount {
    has 'overdraft_account' => ( isa => 'BankAccount', is => 'rw' );

    before withdraw (Num $amount) {
        my $overdraft_amount = $amount - $self->balance();
        if ( $self->overdraft_account && $overdraft_amount > 0 ) {
            $self->overdraft_account->withdraw($overdraft_amount);
            $self->deposit($overdraft_amount);
        }
    }
}

我认为这很酷,我自己。 :)这是Perl的对象系统上的一层,因此它可以与您已经拥有的东西一起使用(基本上)。

使用Moose,您可以非常轻松地创建子类型,因此您可以确保输入有效。懒惰的程序员同意:要使子类型在驼鹿起作用,必须做得很少,这样做比没有更容易! (从 食谱4)

subtype 'USState'
    => as Str
    => where {
           (    exists $STATES->{code2state}{ uc($_) }
             || exists $STATES->{state2code}{ uc($_) } );
       };

TADA,USSTATE现在是您可以使用的类型!没有大惊小怪,没有穆斯,只有少量代码。如果不正确,它将丢弃错误,并且您班级的所有消费者都必须通过该字符串传递标量。如果很好(应该是...对吗?那真是太好了!

驼鹿有很多这样的很棒的东西。

相信我。一探究竟。 :)

其他提示

在珀尔,

  • 要求 use strictuse warnings 在代码的100%中打开

  • 您可以尝试通过创建几乎私人会员变量 关闭. 。一个很好的例子是“私人成员变量,某种”部分 http://www.usenix.org/publications/login/1998-10/perl.html 。除非您真正知道自己在做什么(并要求他们阅读代码并进行研究以了解如何),否则它们不是100%私人的,而是相当不明显的访问方式。

  • 如果您不想使用封闭,则以下方法效果很好:

    使所有对象成员变量(又称perl中的对象哈希键)包裹在访问器中。有多种方法可以从编码标准POV中有效地执行此操作。最不安全的是class :: concector :: fast。我确定驼鹿有更好的方法,但我对驼鹿不太熟悉。

    确保在私人规定名称中“隐藏”实际成员变量,例如 $object->{'__private__var1'} 将是会员变量,并且 $object->var1() 将是一个getter/setter访问者。

    注意:对于最后的class :: concector :: fast是不好的,因为其成员变量与登录器共享名称。但是,您可以拥有非常简单的构建器,就像class :: concector ::快速创建关键值,例如$ obj-> {'__ private_er_foo'},例如“ foo”。

    这不会阻止他们在脚上射击,但会使这样做更加困难。

    在您的情况下,如果他们使用 $obj->goo 或者 $obj->goo(), ,至少在Perl中,他们会遇到运行时错误。

    他们当然可以竭尽所能 $obj->{'__private__goo'}, ,但是,如果他们因懒惰而做奇闻趣事牛仔,那么后者比做正确的工作要多得多 $obj->foo().

    您也可以进行代码库的扫描,以检测到 $object->{"_ 键入字符串,尽管从您的描述来看,这可能无法成为如此之多。

您可以使用 class :: insideout 或者 对象:: insideout 为您提供真实的数据隐私。祝福的标量参考不是将数据存储在有福的哈希参考中,而是用作词汇数据哈希的关键。长话短说,如果您的同事尝试 $obj->{member} 他们将获得运行时间错误。没有什么 $obj 除了通过访问者之外,他们可以抓住数据,也没有简单的方法来获取数据。

这是 对内而外技术和各种实现的讨论.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top