如何检查perl OO代码中的未定义键?

时间:2012-01-13 09:42:18

标签: perl

我的perl脚本中有use strict;use warnings;;

但无法找到此错误:

sub new {
     #....
     my $self={};
     $self->{databas}="..."; # 'e' is missing
     #....
}

sub foo {
    my $self=shift;
    print $self->{database}; # undef
 }

我花了好几个小时才发现该数据库在sub new中被拼错了。

use strict;use warnings;没有帮助。

如何避免此错误?

5 个答案:

答案 0 :(得分:8)

使用Hash::Util限制/锁定哈希值。


或者,使用Moose来描述您的类,使拼写错误的属性成为运行时错误。

package MyClass;
use Moose;
has 'database' => (isa => 'Str', is => 'rw', default => 'quux');

sub foo {
    my ($self) = @_;
    $self->database; # returns quux
    $self->databas;  # Can't locate object method "databas" via package…

答案 1 :(得分:1)

使用defined//运算符(如果你有perl 5.10 /更高版本)

print "not defined" if !defined $a; # check if $a is undef 

print $a // 'undefed!';             # print a if availiable, "undefed!" otherwise

请参阅http://perldoc.perl.org/functions/defined.htmlhttp://perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or

答案 2 :(得分:1)

使用getter和setter代替哈希键,或切换到Moose。

答案 3 :(得分:1)

如果您看到丢弃的哈希,您认为您会发现它吗?像这样:

$self = bless( {
                 'anotherfield' => 'something else',
                 'databas' => '...',
                 'afield' => 'something'
               }, 'MyClass' );

如果你想知道“怎么来'数据库'没有设置?!?!”并且你把它抛弃了,你觉得这会有帮助吗? “哦,它分配'数据库'而不是'数据库'!”

然后Data::Dumper是最小的Perl调试工具

use Data::Dumper;
...
# Why isn't database assigned?!?!
say Data::Dumper->Dump( [ $self ], [ '$self' ] );

当然,最方便的Data::Dumper工具形式是Smart:Comments

use Smart::Comments;
...
### $self

哪个输出:

### $self: bless( {
###                 afield => 'something',
###                 anotherfield => 'something else',
###                 databas => '...'
###               }, 'MyClass' )

它不是像 Moose 那样预防性工具,但它会节省小时。我认为它甚至可以帮助你学习Perl技巧和实践,因为你会泄漏CPAN对象的内容。当您了解底层结构时,您可以在CPAN模块中搜索。

就像我说的那样,它解决了小时追踪错误的问题(通常足够)。

答案 4 :(得分:0)

另一种方法是使用核心模块Class::Struct

package MyObj;

use Class::Struct;

struct(
    databas => '$',
    # ...
);

1;

package main;

# create object
my $obj = MyObj->new(databas => 'MyDB');

# later
print $obj->database;

运行此操作会导致以下错误:

Can't locate object method "database" via package "MyObj" at ... .