简体   繁体   中英

How to check undefined key in perl OO code?

I have use strict;use warnings; in my perl script;

But this error cannot be found:

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

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

I have spend hours to found out that database in mispelled in sub new .

use strict;use warnings; didnt help.

How can I avoid this error?

Restrict/lock hashes with Hash::Util .


Alternatively, use Moose to describe your classes, making a misspelled attribute a run-time error.

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…

use defined , or // operator (if you have perl 5.10/later)

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

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

See http://perldoc.perl.org/functions/defined.html and http://perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or

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

Do you think you would have spotted it if you saw the hash dumped out? Like this:

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

If you were wondering "How come 'database' isn't set?!?! " and you dumped this out, do you think that would help? "Oh it assigned 'databas' not 'database'!"

Then Data::Dumper is the minimal Perl debugging tool

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

Of course, the most convenient form of Data::Dumper tools is Smart:Comments .

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

Which outputs:

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

It's not as preventative a tool as Moose but it will save hours , though. I think it even helps you learn Perl tricks and practices as you spill out the guts of CPAN objects. When you know the underlying structure, you have something to search for in CPAN modules.

Like I said, it solves the problem of hours tracking down bugs (often enough).

Another approach is to use the core module Class::Struct .

package MyObj;

use Class::Struct;

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

1;

package main;

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

# later
print $obj->database;

Running this results in the following error:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM