23

私は数年前からPerlを書いていますが、これはテキスト処理に適した言語です(私が取り組んでいる遺伝学/ゲノミクスの問題の多くは、テキスト処理の問題に簡単に還元されます)。言語としてのPerlは非常に寛容であり、Perlで非常に貧弱で機能的なコードを書くことは可能です。つい先日、私の友人は、Perlを書き込み専用言語と呼んでいると言いました。一度書いて、一度理解して、終わった後に戻って修正しようとしないでください。

私は時々悪いスクリプトを書いたことで間違いなく罪を犯しましたが、Perlで非常に明確で保守しやすいコードも書いたように感じます。しかし、誰かが私にコードを明確で保守しやすいものにする理由を尋ねた場合、私は自信を持って答えることができません。

Perlコードを保守可能にする理由は何ですか?あるいは、もっと良い質問は、Perlコードを維持するのが難しい理由です。コードを保守するのは私だけではなく、私のような他の貢献者はプロのPerlプログラマーではなく、プログラミングの経験を持つ科学者であると仮定しましょう。

4

8 に答える 8

33

Perl コードを保守できない理由は何ですか? 他のプログラムを保守不可能にするほとんどすべて。明確に定義されたタスクを実行することを目的とした短いスクリプト以外のものを想定すると、これらは次のとおりです。

  • グローバル変数
  • 関心の分離の欠如: モノリシック スクリプト
  • 自己文書化識別子 (変数名とメソッド名) を使用しないでください。たとえば、変数の目的がその名前からわかるはずです。$c悪い。$countより良い。$token_count良い。
    • 識別子をスペルアウトします。プログラムのサイズはもはや重要な問題ではありません。
    • 呼び出されたサブルーチンまたはメソッドdoWorkは何も言わない
    • 別のパッケージからのシンボルのソースを簡単に見つけられるようにします。明示的なパッケージ プレフィックスを使用するか、 経由で使用されるすべてのシンボルを明示的にインポートしuse MyModule qw(list of imports)ます。
  • Perl 固有:
    • ショートカットとあいまいな組み込み変数への過度の依存
    • サブルーチン プロトタイプの悪用
    • 使わないstrict・使わないwarnings
  • 確立されたライブラリを使用するのではなく、車輪を再発明する
  • 一貫したインデント スタイルを使用していない
  • 読者を誘導するために水平および垂直の余白を使用しない

などなど

基本的に、Perl が-f>@+?*<.-&'_:$#/%!.

人々は、Perl プログラマーが楽しみのために行うこと (JAPH、ゴルフなど) と、優れた Perl プログラムがどのように見えるべきかを混同する傾向があります。

IOCCC用に書かれたコードを保守可能なCからどのように分離できるのか、私はまだはっきりしていません.

于 2010-12-03T19:35:14.803 に答える
15

私は提案します:

  1. Perl を巧みに使いすぎないでください。コードでゴルフを始めると、コードが読みにくくなります。あなたが書くコードは、巧妙である必要がある以上に、読みやすく明確である必要があります。
  2. コードを文書化します。モジュールの場合は、一般的な使用方法と方法を説明する POD を追加します。プログラムの場合は、POD を追加して、コマンド ライン オプションと一般的な使用方法を説明します。毛むくじゃらのアルゴリズムがある場合は、それを文書化し、可能であれば参照 (URL) を提供してください。
  3. /.../x 形式の正規表現を使用し、それらを文書化します。誰もが正規表現をよく理解しているわけではありません。
  4. カップリングとは何か、および高/低カップリングの長所/短所を理解してください。
  5. 結束とは何か、結束の高低の長所と短所を理解します。
  6. モジュールを適切に使用してください。適切に定義され、適切に含まれたコンセプトが優れたモジュールになります。そのようなモジュールの再利用が目標です。モノリシック プログラムのサイズを縮小するためだけにモジュールを使用しないでください。
  7. コードの単体テストを記述します。優れたテスト スイートは、コードが今日だけでなく明日も機能することを証明できるようにします。また、古いアプリケーションを壊していないという確信を持って、将来、より大胆な変更を加えることができます。何かを壊すとしたら、まあ、テスト スイートが十分に広範ではなかったということです。

しかし全体として、保守性について質問するほど保守性に気を配っているという事実は、あなたがすでに適切な立場にあり、正しい方法で考えていることを示しています。

于 2010-12-03T19:59:04.273 に答える
13

私はPerl Best Practicesのすべてを使用しているわけではありませんが、それが Damian が書いた目的です。すべての提案を使用するかどうかにかかわらず、それらはすべて少なくとも検討する価値があります。

于 2010-12-03T23:03:58.030 に答える
9

Perl コードを保守しやすくするものは何ですか?

少なくとも:

use strict;
use warnings;

プログラムを読みやすく、理解しやすく、維持しやすくする一般的なガイドラインについては、perldoc perlstyleを参照してください。

于 2010-12-03T19:34:47.343 に答える
5

他の回答で言及されていない、コードの読みやすさにとって非常に重要な要素の 1 つは、空白の重要性です。これは、Perl に依存せず、ある意味で Perl 固有です。

Perl を使用すると、非常に簡潔なコードを記述できますが、簡潔なチャンクは、それらをすべてまとめてまとめる必要があるという意味ではありません。

読みやすさについて話しているとき、空白には多くの意味/用途があります。それらすべてが広く使用されているわけではありませんが、最も役立ちます。

  • トークンを視覚的に分離しやすくするために、トークンの周りにスペースを入れます。

    Perl では、ベスト スタイルの Perl コードでもライン ノイズ文字が蔓延しているため、このスペースは二重に重要です。

    $myHashRef->{$keys1[$i]}{$keys3{$k}}生産緊急事態の真っ只中の午前 2 時は、間隔を空けた場合に比べて読みにくいことがわかりまし た$myHashRef->{ $keys1[$i] }->{ $keys3{$k} }

    補足として、コードが多くのネストされた参照式をすべて同じルートで開始していることがわかった場合は、そのルートを一時ポインターに割り当てることを絶対に検討する必要があります (Sinan のコメント/回答を参照)。

    これの部分的ではあるが非常に重要な特殊なケースは、もちろん正規表現です。この違いは、私が覚えているすべての主要な資料 (PBP、RegEx O'Reilly の本など) で明らかに説明されているので、誰かがコメントで例を要求しない限り、この記事をこれ以上長くすることはありません。

  • 正確で均一なインデント。ああ。明らかに。それでも、コードの半分が 4 文字のタブを使用するエディターと 8 文字のタブを使用するエディターによってタブでインデントされている場合、コードの半分がタブでインデントされている場合、あまりにも多くのコードがあまりにも多く見られます。血まみれのエディターをソフト (スペース エミュレートなど) TAB を実行するように設定するだけで、他の人を惨めにしないでください。

  • 論理的に分離されたコード単位 (ブロックと行のセットの両方) の周りの空行。10000 行の良い Perl で 10000 行の Java プログラムを書くことができます。読みやすくするために、1000 行に 100 ~ 200 行の空行を追加しても、ベネディクト アーノルドのように感じる必要はありません。

  • 非常に長い式を複数の行に分割し、その後に...

  • 垂直方向の配置を修正します。次の違いをご覧ください。

    if ($some_variable > 11 && ($some_other_bigexpression < $another_variable || $my_flag eq "Y") && $this_is_too_bloody_wide == 1 && $ace > my_func() && $another_answer == 42 && $pi == 3) {
    

    if ($some_variable > 11 && ($some_other_bigexpression < $another_variable || 
        $my_flag eq "Y") && $this_is_too_bloody_wide == 1 && $ace > my_func()
        && $another_answer == 42 && $pi == 3) {
    

    if (   $some_variable > 11
        && ($some_other_bigexpression < $another_variable || $my_flag eq "Y")
        && $this_is_too_bloody_wide == 1
        && $ace > my_func()
        && $another_answer == 42
        && $pi == 3) {
    

    個人的には、LHS と RHS を揃えることによって、垂直方向の配置をもう 1 ステップ修正することを好みます (これは、長い SQL クエリの場合に特に読みやすくなりますが、Perl コード自体でも、このような長い条件文と多くの行の割り当てとハッシュ/配列の初期化):

    if (   $some_variable               >  11
        && ($some_other_bigexpression   <  $another_variable || $my_flag eq "Y")
        && $this_is_too_bloody_wide    ==  1
        && $ace                         >  my_func()
        && $another_answer             ==  42
        && $pi                         ==  3  ) {
    

    補足として、場合によっては、そもそもそのような長い式を持たないことで、コードをさらに読みやすく/保守しやすくすることができます。たとえば、if(){}ブロックの内容が aの場合、それぞれが return ブロックを持つreturn複数のif/unlessステートメントを実行する方がよい場合があります。

于 2010-12-04T02:46:24.060 に答える
4

私はこれを、perl が読めないと言われ、自分のコードの保守性について思い込みを始めている人々の問題だと考えています。読みやすさを高品質のコードの特徴と見なすほど良心的であれば、この批判は当てはまらない可能性があります。

可読性について議論するとき、ほとんどの人は正規表現を引き合いに出します。正規表現は perl に組み込まれた DSL であり、読むかどうかのどちらかです。誰かが多くの言語にとって非常に基本的で不可欠なことを理解するのに時間をかけることができない場合、私は推論された認知ギャップを埋めようとすることを気にしません...彼らはただ立ち上がって、perldocsを読み、必要に応じて質問するべきです. .

他の人は、@_、$ などの短い形式の変数の perl の使用を引用します! などなど、これらはすべて簡単に曖昧さをなくすことができます...私は、perl を Java のように見せることに興味はありません。

これらすべての癖とパーリズムの利点は、その言語で記述されたコードベースが簡潔でコンパクトであることが多いことです。100 行の Java よりも 10 行の Perl を読みたい。

私にとって、「保守性」には単にコードが読みやすいというだけではありません。テストを書き、アサーションを作成します...コードを正しく保つためにperlとそのエコシステムに依存するためにできることはすべて行ってください。

要するに、プログラムは、最初に正しく、次に安全で、次にパフォーマンスが高くなるように作成します....これらの目標が達成されたら、火のそばで丸くなるのが楽しくなるようにすることを心配してください.

于 2010-12-03T21:40:26.410 に答える
2

.pm ファイルのディレクトリ構造に反映されるパッケージング/オブジェクト モデルと言えます。博士号取得のために、後で再利用する Perl コードを大量に作成しました。自動LaTeXダイアグラムジェネレーター用でした。

于 2010-12-03T19:31:06.493 に答える
1

Perl を保守しやすくするために、いくつかのポジティブなことを話します。

通常、非常に密度の高いステートメントを使用して巧妙になりすぎるべきではないことは事実ですがreturn !$@;#%、リスト処理演算子、 likemapおよびgreplist-context は、 like ofsplitおよび similar 演算子から順番に返されます。機能的なスタイルでコードを書くことは、保守性にプラスの貢献をすることができます。私の最後の雇用主には、同様の方法で機能するいくつかのおしゃれなハッシュ操作関数もありました ( hashmapand hashgrep、技術的には偶数サイズのリストしか与えませんでした)。例えば:

# Look for all the servers, and return them in a pipe-separated string
# (because we want this for some lame reason or another)
return join '|', 
       sort
       hashmap {$a =~ /^server_/ ? $b : +()} 
       %configuration_hash;

Higher Order Perlも参照してください。

于 2012-07-05T23:23:21.837 に答える