質問
私は数年前からPerlを書いてきましたが、それはテキスト処理のための私の好ましい言語です(私が取り組んでいる遺伝学/ゲノミクスの問題の多くは、テキスト処理の問題に容易に削減されます)。言語としてのPerlは非常に寛容であり、Perlで非常に貧弱だが機能的なコードを書くことが可能です。ちょうど先日、私の友人は彼がパールを呼んでいると言った 書き込み専用 言語:一度書いて、一度理解してください、そして、それが終わってから戻って修正しようとしないでください。
私は間違いなく悪いスクリプトを書くことで罪を犯していましたが、Perlで非常に明確で保守可能なコードも書いたように感じます。しかし、誰かが私に何を尋ねたら 作る コードは明確で保守可能ですが、自信を持って答えを出すことはできません。
Perlコードが保守可能な理由は何ですか?それとも、より良い質問は、Perlコードを維持するのを難しくする理由です。コードを維持するのは私だけではないと仮定しましょう。私のような他の貢献者は、プロのPerlプログラマーではなく、プログラミングの経験を持つ科学者であると仮定しましょう。
解決
Perl Codeの維持不可能な理由は何ですか?他のプログラムを維持不可能にするほとんどのもの。明確に定義されたタスクを実行することを意図した短いスクリプト以外のものを仮定すると、これらは次のとおりです。
- グローバル変数
- 懸念の分離の欠如:モノリシックスクリプト
- 自己文書化識別子(変数名とメソッド名)を使用していません。たとえば、変数の目的がその名前から何であるかを知っておく必要があります。
$c
悪い。$count
より良い。$token_count
良い。- スペル識別子。プログラムのサイズは、もはや最重要の懸念事項ではありません。
- サブルーチンまたは呼び出された方法
doWork
何も言わない - 別のパッケージからシンボルのソースを簡単に見つけることができます。明示的なパッケージプレフィックスを使用するか、使用するすべてのシンボルを明示的にインポートするか
use MyModule qw(list of imports)
.
- Perl固有:
- ショートカットと不明瞭なビルトイン変数への過度の依存
- サブルーチンのプロトタイプの乱用
- 使用していない
strict
使用していませんwarnings
- 確立されたライブラリを使用するのではなく、ホイールを再発明します
- 一貫したインデントスタイルを使用していません
- 読者を導くために水平と垂直の空白を使用していない
などなど
基本的に、Perlがそうであると思うなら -f>@+?*<.-&'_:$#/%!
, 、そして、あなたはそのようなものを本番コードで書くことを目指しています、そして、ええ、あなたは問題があるでしょう。
人々は、Perlプログラマーが楽しみのために(たとえば、Japhs、Golfなど)、優れたPerlプログラムがどのように見えるかを混乱させる傾向があります。
私は彼らがどのように彼らの心の中で分離できるかについてまだ不明です コード のために書かれています IOCCC 保守可能なCから
他のヒント
私は提案します:
- Perlで賢くなりすぎないでください。コードでゴルフのプレイを開始すると、読みやすいコードが難しくなります。あなたが書くコードは、賢くする必要がある以上に読みやすく、明確にする必要があります。
- コードを文書化します。モジュールの場合は、典型的な使用法と方法を説明するポッドを追加します。プログラムの場合は、ポッドを追加してコマンドラインオプションと典型的な使用法を説明します。毛むくじゃらのアルゴリズムがある場合は、それを文書化し、可能であれば参照(URL)を提供します。
- /...../x形式の正規表現を使用し、それらを文書化します。誰もが正規表現をよく理解しているわけではありません。
- カップリングとは何か、および高/低結合の長所/短所を知ってください。
- 凝集とは何か、および高い/低凝集の長所/短所を知ってください。
- モジュールを適切に使用します。明確に定義された、よく完結したコンセプトは、素晴らしいモジュールになります。そのようなモジュールの再利用が目標です。単にモノリシックプログラムのサイズを縮小するためにモジュールを使用しないでください。
- あなたのコードのためのユニットテストを書きます。優れたテストスイートは、コードが今日機能していることを証明できるだけでなく、明日も証明できるようになります。また、古いアプリケーションを壊していないという自信を持って、将来的に大胆な変更を加えることができます。物事を壊すと、テストスイートは十分に広くありませんでした。
しかし、全体として、あなたがそれについて質問することができるメンテナビリティに十分な関心を持っているという事実は、あなたがすでに良い場所にいて、正しい方法を考えていることを教えてくれます。
私はすべてを使うわけではありません Perlのベストプラクティス, 、しかし、それはダミアンが書いたものです。私がすべての提案を使用するかどうかにかかわらず、それらはすべて少なくとも検討する価値があります。
Perlコードが保守可能な理由は何ですか?
少なくとも:
use strict;
use warnings;
見る perldoc perlstyle プログラムを読み取り、理解し、維持しやすくする一般的なガイドラインの場合。
他の答えで言及されていない読みやすさをコードするために非常に重要な要因の1つは、空白の重要性であり、これはPerlに依存しないものであり、ある意味ではPerl固有のものです。
Perlでは、非常に簡潔なコードを書くことができますが、考慮して、チャンクはすべて一緒に束ねられなければならないという意味ではありません。
ホワイトスペースには、読みやすさについて話しているときに多くの意味/用途がありますが、それらのすべてが広く使用されているわけではありませんが、最も便利です。
トークンの周りのスペースを視覚的に簡単に分離します。
このスペースは、ベストスタイルのPERLコードであっても、ラインノイズ文字の有病率のため、Perlで二重に重要です。
私は見つけます
$myHashRef->{$keys1[$i]}{$keys3{$k}}
生産緊急事態の途中で午前2時に、間隔を空けた場合と比較して読みやすくすることは以下を行います。$myHashRef->{ $keys1[$i] }->{ $keys3{$k} }
.サイドノートとして、コードがすべて同じルートから始まる多くの深いネストされた参照式を実行していることがわかった場合は、そのrootを一時的なポインターに割り当てることを絶対に検討する必要があります(Sinanのコメント/回答を参照)。
これの部分的で非常に重要な特別なケースは、もちろん正規表現です。違いは、私が思い出すすべての主要な資料(PBP、Regex O'Reilly Bookなど)で死亡して説明されていたので、誰かがコメントの例を要求しない限り、この投稿をさらに延長することはありません。
正確で均一なインデント。 D'OH。明らかに。しかし、編集者が4文字のタブを使用した人とエディターが8文字のタブを使用した人によって別の人によってタブによってインデントされた場合、コードの半分がタブでインデントされた場合、コードの半分がタブでインデントされた場合、コードが100%読みにくいコードが100%読みにくくなりすぎています。血まみれの編集者を柔らかい(スペース排出)タブを実行するように設定し、他の人を悲惨にしないでください。
論理的に個別のコードユニットの周りの空の行(両方のブロックと単なる行のセット)。 1000ラインの良いPerlで10000ラインJavaプログラムを書くことができます。これらの1000に100-200の空のラインを追加して、物事をより読みやすくするために、ベネディクトアーノルドのように感じないでください。
Uber-Long式を複数の行に分割し、それに続いて...
正しい垂直アライメント。間の違いを目撃してください:
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クエリだけでなく、このような長い条件と多くの課題と多くの課題の両方で、特に読みやすいです。ハッシュ/配列初期化):
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
, 、それから複数のことをしますif/unless
それぞれに戻るブロックがあるステートメントの方が良いかもしれません。
これは、Perlが読めないと言われている人々の問題と考えており、彼らは自分のコードの維持可能性について仮定し始めています。あなたが読みやすさを質の高いコードの特徴と見なすほど良心的であるならば、この批判があなたに当てはまらない可能性があります。
ほとんどの人は、読みやすさについて議論するとき、正規表現を引用します。正規表現はPerlに埋め込まれたDSLであり、読み取るかどうかのどちらかです。誰かが時間をかけて多くの言語にとって非常に基本的で不可欠なものを理解できない場合、私は推測された認知ギャップを橋渡ししようとすることを心配していません...彼らはただ人間を持ち、perldocsを読んで、必要に応じて質問する必要があります。
他の人は、@_、$!などの短編VARのPerlの使用を引用します。など。これらはすべて簡単に曖昧に見られます...私はPerlをJavaのように見せることに興味がありません。
これらのすべての癖とパーリズムの利点は、言語で記述されたコードベースがしばしば簡潔でコンパクトであるということです。私はむしろ、100行のJavaよりも10行のPerlを読みたいです。
私には、単に読みやすいコードを持っているだけでなく、「保守性」には非常に多くのことがあります。テストを書き、主張をします... Perlとそのエコシステムに頼るためにあなたができる他のすべてを実行して、コードを正しく保ちます。
要するに、プログラムを最初に正しく、次に安全にし、次にパフォーマンスを発揮するように書いてください。これらの目標が満たされたら、火の近くで丸くなることを心配します。
.pmファイルのディレクトリ構造に反映されるパッケージング/オブジェクトモデルがあります。私の博士号のために、私はかなりの多くのPerlコードを書きました。自動ラテックス図ジェネレーター用でした。
話します ポジティブ Perlを維持可能にするもの。
あなたが通常、本当に濃い声明であまりにも賢くならないはずです return !$@;#%
同様ですが、リスト処理演算子を使用して巧妙な量の賢さがあります。 map
と grep
list-contextは、ようなものから返されます split
同様のオペレーターは、機能スタイルでコードを作成するために、保守性にプラスの貢献をすることができます。私の最後の雇用主に、私たちは同様の方法で働いたいくつかのおしゃれなハッシュ操作機能も持っていました(hashmap
と 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;
参照してください 高次のperl, http://hop.perl.plover.com - メタプログラムをメタプログローミング自体を邪魔にならないようにすることができれば、メタプログラムを適切に使用できます。