现在,由于缺乏更好的方法,我公司的大多数程序员都不是很聪明.更糟糕的是,他们不喜欢阅读文档,并且似乎在理解其他人的代码时遇到了问题.牛仔编码就是这里的游戏.每当他们遇到问题并尝试解决问题时,他们就会想出一个可怕的解决方案,实际上什么也解决了,通常会让事情变得更糟.
坦率地说,这导致我不相信用鸭子类型语言编写的代码.作为一个例子,我看到太多问题,他们没有得到滥用对象的明确错误.例如,如果类型A具有成员foo,并且它们执行类似instance-> goo的操作,则它们不会立即看到问题.它将返回一个null / undefined值,它们可能会浪费一个小时来查找原因.然后最终改变别的东西,因为他们没有正确识别原始问题.
因此,我正在集思广益,以保持我的脚本语言(快速开发是一个优势),但在对象未正确使用时给出明确的错误消息.我意识到,由于没有编译阶段或静态类型,错误必须在运行时.我很好,只要用户得到一个非常明确的通知说“这个对象没有X”
作为我的解决方案的一部分,我不希望在尝试使用它之前检查方法/变量是否存在.
虽然我的工作是在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,您可以非常轻松地创建子类型,这样您就可以确保输入有效.懒惰的程序员同意:由于在Moose中使子类型工作所以必须做的很少,所以更容易做到而不是! (自Cookbook 4起)
subtype 'USState' => as Str => where { ( exists $STATES->{code2state}{ uc($_) } || exists $STATES->{state2code}{ uc($_) } ); };
而Tada,USState现在是一种你可以使用的类型!没有大惊小怪,没有muss,只有少量的代码.如果它不对,它会抛出一个错误,而你的类的所有消费者必须做的是传递带有该字符串的标量.如果它没问题(应该是……对吗?:))他们像平常一样使用它,你的类可以防止垃圾.那太好了!
穆斯有很多很棒的东西.
相信我.看看这个.