2010-02-16 6 views
16

In letzter Zeit habe ich beschlossen, Perl::Critic häufiger auf meinem Code zu verwenden. Nachdem ich nun seit fast 7 Jahren in Perl programmiert habe, bin ich schon lange mit den meisten Best Practices von Perl vertraut, aber ich weiß, dass es immer noch Raum für Verbesserungen gibt. Eine Sache, die mich jedoch nervt ist die Tatsache, dass Perl::Critic nicht gefällt, wie ich @ _ für Unterprogramme entpacke. Als Beispiel:Warum lehnt Perl :: Critic die Verwendung von shift zum Auffüllen von Unterprogrammvariablen ab?

sub my_way_to_unpack { 
    my $variable1 = shift @_; 
    my $variable2 = shift @_; 

    my $result = $variable1 + $variable2; 
    return $result; 
} 

Dies ist, wie ich es immer getan habe, und wie seine auf beiden PerlMonks und Stack-Überlauf diskutiert worden ist, seine not necessarily evil entweder.

Ändern der Codeausschnitt oben ...

sub perl_critics_way_to_unpack { 
    my ($variable1, $variable2) = @_; 

    my $result = $variable1 + $variable2; 
    return $result; 
} 

... funktioniert auch, aber ich finde es schwerer zu lesen. Ich habe auch Damian Conways Buch Perl Best Practices gelesen und ich verstehe nicht wirklich, wie mein bevorzugter Ansatz zum Entpacken unter seinen Vorschlag fällt, @_ direkt zu verwenden, wie Perl::Critic impliziert. Ich habe immer den Eindruck, dass Conway spricht über Bösartigkeit wie:

sub not_unpacking { 
    my $result = $_[0] + $_[1]; 
    return $result; 
} 

Das obige Beispiel ist schlecht und schwer zu lesen, und ich würde nie die Ansicht, dass der Produktionscode in einem Stück zu schreiben.

Also kurz gesagt, warum Perl::Critic meinen bevorzugten Weg schlecht betrachten? Mache ich wirklich ein abscheuliches Verbrechen, indem ich die Schicht auspacke?

Wäre das etwas, das andere Leute als ich denken sollten mit den Perl::Critic Betreuer aufgewachsen sein?

+2

Bei einer Schätzung, Perl :: Critic mag es nicht, weil es funktioniert mit "Magie", wie zum Beispiel 'shift' auf' @ _', wenn keine Variable angegeben ist. Es wäre hilfreich zu wissen, welche Perl :: Critic-Regel dies ändern möchte. – Powerlord

+4

Wenn Sie die Listenform der Zuweisung verwenden, kann Komodo Edit/IDE Ihnen die Argumente für eine Subroutine mitteilen. –

+1

Dank Brad, das habe ich nicht bemerkt. Ich bin ein alter ViM-Benutzer, also ignoriere ich normalerweise, was Komodo Edit mir vorsetzt, aber ich habe mich immer gefragt, wie das funktioniert. – Weegee

Antwort

11

Die einfache Antwort ist, dass Perl :: Critic PBP hier nicht folgt. Die Buch explizit besagt, dass die Schicht Idiom ist nicht nur akzeptabel, aber ist in einigen Fällen tatsächlich bevorzugt.

+0

Wenn ich heute Abend nach Hause komme Ich werde das Buch aufschlagen und den Abschnitt noch einmal durchlesen müssen, es ist schon eine Weile her, aber ich denke, Sie könnten recht haben. – Weegee

+0

Ja, das kann ich jetzt bestätigen. – Weegee

8

Es ist wichtig, daran zu denken, dass viele der Sachen in Perl Best Practices nur die Meinung eines Kerls darüber ist, was am besten aussieht oder am einfachsten zu arbeiten ist, und es spielt keine Rolle, ob man es anders macht. Damian sagt das im einführenden Text des Buches. Das ist nicht zu sagen, es ist alle so - es gibt viele Dinge in dort, die absolut notwendig sind: mit strict, zum Beispiel.

So wie Sie Ihren Code schreiben, müssen Sie selbst entscheiden, was Ihre eigenen Best Practices sein werden, und die Verwendung von PBP ist so gut wie ein Ausgangspunkt. Bleiben Sie dann mit Ihren eigenen Standards konsistent.

Ich versuche, die meisten Sachen in PBP zu folgen, aber Damian kann meine Subroutine-Argument shift s und meine unless es, wenn er sie aus meinen kalten, toten Fingerspitzen pries.

Wie bei Critic können Sie auswählen, welche Richtlinien Sie erzwingen möchten, und sogar Ihre eigenen erstellen, wenn sie noch nicht existieren.

+1

Das ist ein ausgezeichneter Punkt, und ich stimme ihm zu, aber meine Sorge ist, ob Perl :: Critic in seinem Standardzustand richtig ist, wenn er sagt, dass Unterroutine-Argument-Verschiebung schlecht ist. – Weegee

9

Das Ausführen perlcritic mit --verbose 11 erläutert die Richtlinien. Es sieht jedoch nicht so aus, als ob diese beiden Erklärungen auf Sie zutreffen.

 
Always unpack @_ first at line 1, near 
'sub xxx{ my $aaa= shift; my ($bbb,$ccc) = @_;}'. 
    Subroutines::RequireArgUnpacking (Severity: 4) 
    Subroutines that use `@_' directly instead of unpacking the arguments to 
    local variables first have two major problems. First, they are very hard 
    to read. If you're going to refer to your variables by number instead of 
    by name, you may as well be writing assembler code! Second, `@_' 
    contains aliases to the original variables! If you modify the contents 
    of a `@_' entry, then you are modifying the variable outside of your 
    subroutine. For example: 

     sub print_local_var_plus_one { 
      my ($var) = @_; 
      print ++$var; 
     } 
     sub print_var_plus_one { 
      print ++$_[0]; 
     } 

     my $x = 2; 
     print_local_var_plus_one($x); # prints "3", $x is still 2 
     print_var_plus_one($x);  # prints "3", $x is now 3 ! 
     print $x;      # prints "3" 

    This is spooky action-at-a-distance and is very hard to debug if it's 
    not intentional and well-documented (like `chop' or `chomp'). 

    An exception is made for the usual delegation idiom 
    `$object->SUPER::something(@_)'. Only `SUPER::' and `NEXT::' are 
    recognized (though this is configurable) and the argument list for the 
    delegate must consist only of `(@_)'. 
+1

Das ist auch der Grund, warum ich besorgt bin, ob Perl :: Critic den "Immer entpacken @_" Fall gültig prüft ... – Weegee

+1

+1 für '--verbose 11' – sebthebert

2

In einigen Fällen kann Perl :: Critic PBP-Richtlinien nicht genau erzwingen, so dass es eine Annäherung erzwingen kann, die versucht, den Geist der Conway-Richtlinien zu entsprechen. Und es ist durchaus möglich, dass wir PBP falsch interpretiert oder falsch angewendet haben. Wenn Sie etwas finden, das nicht richtig riecht, senden Sie bitte einen Fehlerbericht an [email protected] und wir werden uns sofort darum kümmern.

Danke,

-Jeff

+0

Danke für das Posten hier Jeff. Ich werde morgen eine E-Mail an den E-Mail-Account [email protected] senden, in der ich meine Bedenken darlege. Ich ging zurück und las Abschnitt 9.3 in Conways Buch nochmals und er sagt sogar: "Alternativ können Sie eine Reihe von getrennten Schichtaufrufen als ersten Absatz des Unterprogramms verwenden". – Weegee

0

Ich denke, Sie in der Regel Verschiebung vermeiden sollte, wenn es nicht wirklich notwendig ist!

lief einfach in einen Code wie folgt aus:

sub way { 
    my $file = shift; 
    if (!$file) { 
    $file = 'newfile'; 
    } 
    my $target = shift; 
    my $options = shift; 
} 

Wenn Sie etwas in diesem Code beginnen zu ändern, gibt es eine gute Chance, dass Sie accidantially die Reihenfolge der Verschiebungen ändern könnte oder vielleicht ein überspringen und alles geht Southway . Außerdem ist es schwer zu lesen - weil Sie nicht sicher sein können, dass Sie wirklich alle Parameter für das Sub sehen, weil einige Zeilen darunter möglicherweise eine andere Verschiebung sind ... Und wenn Sie einige Regexes dazwischen verwenden, können sie den Inhalt von $ _ und ersetzen Seltsames Zeug beginnt zu passieren ...

Ein direkter Vorteil der Verwendung des Entpackens my (...) = @_ ist, dass Sie einfach den (...) Teil kopieren und einfügen können, wo Sie die Methode aufrufen und haben eine nette Unterschrift :) Sie können sogar die gleichen Variablennamen verwenden und müssen nichts ändern!

Ich denke shift impliziert Listenoperationen, bei denen die Länge der Liste dynamisch ist und Sie ihre Elemente einzeln behandeln wollen oder wo Sie explizit eine Liste ohne das erste Element benötigen. Aber wenn Sie nur die ganze Liste den X-Parametern zuweisen möchten, sollte Ihr Code das mit meinen (...) = @_; niemand muss sich wundern.

Verwandte Themen