everbox
everbox

Reputation: 1199

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?

Upvotes: 2

Views: 435

Answers (5)

Prakash K
Prakash K

Reputation: 3000

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 ... .

Upvotes: 0

Axeman
Axeman

Reputation: 29854

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).

Upvotes: 1

daxim
daxim

Reputation: 39158

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…

Upvotes: 8

choroba
choroba

Reputation: 241848

Use getters and setters instead of hash keys, or switch to Moose.

Upvotes: 1

J-16 SDiZ
J-16 SDiZ

Reputation: 26910

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

Upvotes: 1

Related Questions