2016-06-01 12 views
0

Ich versuche herauszufinden, wie aus einer Liste von Fehlern (eine konstante Liste) auf einen Fehler zugegriffen wird. Mit Zugriff meine ich, dass ich eine neue() Methode habe, die einen Fehler ausgibt/erzeugt, der gepostet wird. Meine neue Methode stimmt nicht mit der Art und Weise überein, wie meine "Code" -Liste im Moment ist, also frage ich, welche Änderungen ich machen müsste, damit ein Fehler (Hash) aus der Liste wie folgt gefunden werden kann: ASC::Builder:Error->new(code => UNABLE_TO_PING_SWITCH_ERROR, switch_ip => $switch_ip, timeout => $timeout); (falls dies möglich ist, habe ich gesagt, es nicht sein kann, Code als Argument, ohne zu nehmen und dann zu löschen) meine Dateien unterMöchten Sie auf einen Hash aus einer benannten Liste von Konstanten zugreifen, die sich in einem separaten Perl-Modul befinden

Hier sind:

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; 

Type.pm (Dies ist die Liste, die ich exportiere)

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 .: Kann bei Bedarf den Komponententest für dieses Design einschließen.

+0

Wenn was ich tun möchte, ist nicht möglich, wird jemand bitte den Grund warum erklären? :) –

+0

Ihr 'Type.pm' Modul kann aufgrund eines fehlenden'} 'nicht kompiliert werden. Bitte repariere. –

+0

Woops, tut mir leid, ich nahm die ganze Liste der Fehler nur für den Zweck der Frage heraus, da nur ein Fehler benötigt wird, wird jetzt behoben :) –

Antwort

0

Verwenden Sie nicht das Symbol code, es ist das Problem verwirrend.

Sie können Ihre Datei unverändert lassen. Er definiert die Konstante code als Referenz auf einen Hash, der ein Schlüssel/Wert-Paar hat. Der Schlüssel dieses Hashs ist der Name des Fehlers, auf den Sie eventuell zugreifen möchten. In Ihrem Error.pm Modul importieren Sie die Konstante code. Es gibt keinen Grund, das an einen Konstrukteur weiterzugeben. Sie können einfach weitermachen und es benutzen.

Ändern Sie den Anruf zu Ihrem Konstruktor:

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

Dann in Ihrem Konstruktor können Sie tun:

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

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

An diesem Punkt $error_hash wird ein Verweis auf die innere Hash sein, das Sie erstellt in 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', 
} 

und Sie können es entsprechend verwenden Gl. Ich hoffe, dass hilft Ihnen, in die richtige Richtung zu kommen.

+0

Okay so error_hash zeigt Verweis auf den Namen des Fehlers .. Ich kann das verstehen. Enthält error_name das erste Argument, das an die neue Methode übergeben wird? dann wird dieser Name in der Konstantenliste von 'code -> {$ error_name}' –

+1

gefunden. Dies ist die Antwort, nach der ich die ganze Zeit gesucht habe. Ich denke, haha. Ich habe diese Frage ein paar Mal hier gestellt, aber ich konnte nicht bekommen, wonach ich gesucht habe, vielleicht habe ich die Frage falsch gestellt, aber danke dafür, ich werde daran arbeiten !! :) –

+0

''error_name'' ist nur eine Zeichenfolge. Wir verwenden es als Schlüssel im Aufruf des Konstruktors und zeigen auf den Wert "UNABLE_TO_PING_SWITCH_ERROR". (Ich verwende die Begriffe "Schlüssel" und "Wert" hier sehr lose, weil die Parameterliste genau das ist, eine Liste, kein echter Hash, obwohl wir '' '' ''' verwenden, was normalerweise einen Hash anzeigt). Innerhalb des Konstruktors erzeugen wir den Hash '% args' aus der Parameterliste, wobei' 'error_name'' tatsächlich zu einem Schlüssel wird, der auf den Wert 'UNABLE_TO_PING_SWITCH_ERROR' verweist. Diese Zeichenfolge wird dann als Schlüssel für den Hash verwendet, auf den "Code" verweist. –