Как проверить неопределенный ключ в Perl OO-код? - PullRequest
2 голосов
/ 13 января 2012

У меня есть use strict;use warnings; в моем скрипте perl;

Но эта ошибка не может быть найдена:

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 ]

8 голосов
/ 13 января 2012

Ограничить / заблокировать хэши с помощью 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 голос
/ 13 января 2012

Как вы думаете, вы бы заметили это, если бы увидели, что хэш выгружен? Как это:

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

Как я уже сказал, это решает проблему часов отслеживания ошибок (достаточно часто).

1 голос
/ 13 января 2012

Используйте геттеры и сеттеры вместо хеш-ключей или переключитесь на Moose.

1 голос
/ 13 января 2012

используйте оператор 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.html и http://perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or

0 голосов
/ 13 января 2012

Другой подход заключается в использовании основного модуля 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 ... .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...