2016-06-01 3 views
0

Я пытаюсь выяснить, как получить доступ к ошибке из списка ошибок (список констант). Под доступом я имею в виду, что у меня есть метод new(), который выводит/создает сообщение об ошибке. Мой новый метод не соответствует правильному пути моего кода «в данный момент», поэтому я спрашиваю, какие изменения мне придется сделать, чтобы он мог получить ошибку (хэш) из списка следующим образом: ASC::Builder:Error->new(code => UNABLE_TO_PING_SWITCH_ERROR, switch_ip => $switch_ip, timeout => $timeout); (если это возможно, мне сказали, что не может быть, без учета кода в качестве аргумента, а затем удалить его)Хотите получить доступ к хэшу из именованного списка констант, которые находятся в отдельном модуле perl.

Вот мои файлы ниже:

Error.pm

package ASC::Builder::Error; 

    use strict; 
    use warnings; 

    use ASC::Builder::Error::Type 'code'; 


    use parent 'Exporter'; 
    our @EXPORT_OK = qw/new/; 

    sub new { 
     my ($class, %args) = @_; 
     my @args = keys %args; 
     # Takes code in as an argument and then removes it so the error hash it self can be assigned to it 
     my $self = delete $args{code}; 
     if (is_error($self)) { 
      return $self; 
     } 
     # 1st argument will be error hash. Any other arguments will be context params & inserted into 
     # context field of the error hash 
     if (ref $self eq 'HASH' && (@args > 1)) { 
      foreach my $key (@{ $self->{context} }) { 
       # And take the ones we need 
       $self->{args}->{$key} = $args{$key}; 
      } 
      my @template_args = map { $self->{args}->{$_} } @{ $self->{context} }; 

      # Map/Insert arguments into context hash and insert into string template 
      $self->{message} = sprintf ($self->{template}, @template_args); 
      return bless $self, $class; 
      } 
      # Supporting the old error messaage (string & parameters) 
      else { 
       return bless { message => $args[0]}, $class; 
      } 
     } 

     # Accessor for category 
     sub category { 
      return shift->{category}; 
     } 

     # Accessor for message 
     sub template { 
      return shift->{template}; 
     } 
     # Accessor for context 
     sub context { 
      return shift->{context}; 
     } 
     # Accessor for template option 
     sub tt { 
      return shift->{tt}{template}; 
     } 
     # Accessor for fatal 
     sub is_fatal { 
      return shift->{fatal}; 
     } 
     # Setter for is_fatal 
     sub set_is_fatal { 
      my ($self, $fatal) = @_; 
      $self->{fatal} = $fatal; 
     } 

     # Accessor for wiki_page 
     sub wiki_page { 
      return shift->{wiki_page}; 
     } 
    # Accessor for args. args are a hash ref of context parameters that are 
     # passed in as a list at construction 
     sub args { 
      return shift->{args}; 
     } 
     # Accessor for error message which is processed inside the new() method. 
     # Will return error message with context parameters inserted. 
     sub message { 
      return shift->{message}; 

     } 
     # Stringifies the error to a log message (for SB dashboard), including the 
     # category, message, and wiki_page. 
     sub stringify { 
      my ($self) = @_; 
      return sprintf ("%s: %s\nMore info: %s",$self->{category}, $self->{message}, $self->{wiki_page}); 
     } 

     # Accessor for old error message type 
     sub details { 
      my $self = shift; 
      return $self->{details} || $self->{message}; 
     } 
     sub code { 
      return shift->{code}; 
     } 

     # Used to deserializ from build json. 
     sub recreate_from_hash { 
      my($class, $hash) = @_; 
      return bless $hash, $class; 
     } 

     # Use to check if something is out error. 
     sub is_error { 
      if (scalar(@_) > 1) { # Called as $class->is_error 
       shift; # Get rid of class 
      } 
      return UNIVERSAL::isa(shift, 'ASC::Builder::Error'); 
     } 
     1; 

Тип.pm (Это список, который я экспортирую)

package ASC::Builder::Error::Type; 
    use strict; 
    use warnings; 
    use parent 'Exporter'; 

    # Export the list of errors 
    our @EXPORT_OK = ('code'); 

    # List of error messages 
    use constant code => { 
     UNABLE_TO_PING_SWITCH_ERROR => { 
      category => 'Connection Error', 
      template => "Could not ping switch %s in %s seconds.", 
      context => [ qw(switch_ip timeout) ], 
      tt => {template => 'disabled'}, 
      fatal => 1, 
      wiki_page => 'http://w.error-fix.com/index.php/Builder/ErrorCodes/UNABLE_TO_PING_SWITCH_ERROR', 
     }, 
    # Add errors to this library 
    }; 
    1; 

N.B .: Может включать в себя единичный тест для этой конструкции, если это необходимо.

+0

Если то, что я хочу сделать, невозможно, объясните, пожалуйста, почему? :) –

+0

ваш 'Type.pm' модуль не может скомпилироваться из-за отсутствия'} '. Пожалуйста исправьте. –

+0

Woops, извините, я достал весь список ошибок только для цели вопроса, так как требуется только одна ошибка, теперь будет исправлена ​​:) –

ответ

0

Не используйте повторно символ code, это путает проблему.

Вы можете оставить свой файл Type.pm так, как есть. Он определяет константу code как ссылку на хеш с одной парой ключ/значение. Ключ этого хэша - это имя ошибки, к которой вы в конечном итоге хотите получить доступ.

В вашем Error.pm модуле вы импортируете константу code. Нет причин передавать это конструктору. Вы можете просто использовать его.

Изменить вызов вашего конструктора:

ASC::Builder:Error->new(error_name => 'UNABLE_TO_PING_SWITCH_ERROR', switch_ip => $switch_ip, timeout => $timeout); 

Затем в конструкторе, вы можете сделать:

sub new { 
    my ($class, %args) = @_; 
    my $error_name = $args{error_name}; 

    my $error_hash = code->{$error_name}; 

На данный момент $error_hash будет ссылкой на внутренний хэш вы создали в Type.pm:

{ 
     category => 'Connection Error', 
     template => "Could not ping switch %s in %s seconds.", 
     context => [ qw(switch_ip timeout) ], 
     tt => {template => 'disabled'}, 
     fatal => 1, 
     wiki_page => 'http://w.error-fix.com/index.php/Builder/ErrorCodes/UNABLE_TO_PING_SWITCH_ERROR', 
} 

и вы можете использовать его accordin глицин. Надеюсь, это поможет вам в правильном направлении.

+0

Хорошо, поэтому error_hash указывает на ссылку на имя ошибки .. Я могу это понять. Имеет ли error_name первый аргумент, который передается в новый метод? то это имя находится в списке констант с помощью 'code -> {$ error_name}' –

+1

Это ответ, который я искал все время. Я думаю, ха-ха. Я задал этот вопрос несколько раз здесь, но не смог получить то, что искал, может быть, я задал вопрос неправильно, но спасибо за это, я буду работать над этим !! :) –

+0

'' error_name'' - это просто строка. Мы используем его как ключ в вызове конструктора, указывая на значение 'UNABLE_TO_PING_SWITCH_ERROR''. (Я использую термины «ключ» и «значение» здесь очень слабо, потому что список параметров - это просто список, а не реальный хеш, хотя мы используем '=>', который обычно указывает на хеш). Внутри конструктора мы создаем хэш '% args' из списка параметров, после чего' 'error_name' действительно становится ключом, который указывает на значение' UNABLE_TO_PING_SWITCH_ERROR''. Затем эта строка используется как ключ к хэшу, который ссылается на «код». –