模拟鸭子式语言中静态类型的各个方面 [英] Simulating aspects of static-typing in a duck-typed language

查看:99
本文介绍了模拟鸭子式语言中静态类型的各个方面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我目前的工作中,我正在构建一套严重依赖对象的Perl脚本. (在Hash上使用Perl的bless()尽可能接近OO)

In my current job I'm building a suite of Perl scripts that depend heavily on objects. (using Perl's bless() on a Hash to get as close to OO as possible)

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

Now, for lack of a better way of putting this, most programmers at my company aren't very smart. Worse, they don't like reading documentation and seem to have a problem understanding other people's code. Cowboy coding is the game here. Whenever they encounter a problem and try to fix it, they come up with a horrendous solution that actually solves nothing and usually makes it worse.

坦率地说,这导致我不信任以鸭子类型语言编写的代码.作为一个例子,我看到了太多的问题,因为它们没有因滥用对象而出现显式错误.例如,如果类型A具有成员foo,并且它们执行类似instance->goo的操作,则它们不会立即发现问题.它将返回一个空值/未定义的值,他们可能会浪费一个小时来查找原因.然后由于他们没有正确识别出原始问题而改变了其他东西.

This results in me, frankly, not trusting them with code written in duck typed language. As an example, I see too many problems with them not getting an explicit error for misusing objects. For instance, if type A has member foo, and they do something like, instance->goo, they aren't going to see the problem immediately. It will return a null/undefined value, and they will probably waste an hour finding the cause. Then end up changing something else because they didn't properly identify the original problem.

因此,我正在集思广益,以寻求一种保留脚本语言的方法(它的快速开发是一个优势),但是当对象使用不当时会给出明确的错误消息.我意识到,由于没有编译阶段或静态类型,因此错误必须在运行时发生.我对此很好,只要用户得到一个非常明确的通知说此对象没有X"即可.

So I'm brainstorming for a way to keep my scripting language (its rapid development is an advantage) but give an explicit error message when an object isn't used properly. I realize that since there isn't a compile stage or static typing, the error will have to be at run time. I'm fine with this, so long as the user gets a very explicit notice saying "this object doesn't have X"

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

As part of my solution, I don't want it to be required that they check if a method/variable exists before trying to use it.

即使我的工作是在Perl中进行的,我也认为这与语言无关.

Even though my work is in Perl, I think this can be language agnostic.

推荐答案

如果您有添加模块的想法,请尝试 MooseX :: Declare ,这是Perl类最好的接口之一.看看:

If you have any shot of adding modules to use, try Moose. It provides pretty much all the features you'd want in a modern programming environment, and more. It does type checking, excellent inheritance, has introspection capabilities, and with MooseX::Declare, one of the nicest interfaces for Perl classes out there. Take a look:

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对象系统上的一层,因此它可以与您已经拥有的东西一起使用(基本上).

I think it's pretty cool, myself. :) It's a layer over Perl's object system, so it works with stuff you already have (basically.)

使用Moose,您可以非常轻松地创建子类型,因此可以确保输入有效.懒惰的程序员同意:要做很少的工作就可以使子类型在Moose中工作,要做起来比做起来容易! (摘自 Cookbook 4 )

With Moose, you can create subtypes really easily, so you can make sure your input is valid. Lazy programmers agree: with so little that has to be done to make subtypes work in Moose, it's easier to do them than not! (from Cookbook 4)

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

Tada,USState现在是您可以使用的类型!没有大惊小怪,没有混乱,只有少量的代码.如果不正确,它将引发错误,并且该类的所有使用者必须做的就是在其中传递带有该字符串的标量.如果一切正常(应该正确...对吗?:))他们像往常一样使用它,并且可以保护您的类免受垃圾侵害.那太好了!

And Tada, the USState is now a type you can use! No fuss, no muss, and just a small amount of code. It'll throw an error if it's not right, and all the consumers of your class have to do is pass a scalar with that string in it. If it's fine (which it should be...right? :) ) They use it like normal, and your class is protected from garbage. How nice is that!

麋鹿有很多很棒的东西.

Moose has tons of awesome stuff like this.

相信我.一探究竟. :)

Trust me. Check it out. :)

这篇关于模拟鸭子式语言中静态类型的各个方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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