こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

プログラムの可読性が悪いです。対策は?

主にperlを使って、趣味で、プログラムを書いているのですが、処理を加える度、ifと行が増えて、気づけば、エディタ1ページ中に収まらず、非常に読みにくいプログラムになっています。
思いつきでも書きやすく、読みやすい、書き方or対策などはありますでしょうか?

また、以前、プロのプログラマの方のPCスペックを見ると、弘法筆を選ばずと申しますか、ノートPCで解像度が低く、良く、あれだけの大きなプログラムが書けるなぁと感心したことがあります。
画面の大きさとプログラムの書き易さには差が無いのでしょうか?
私など、ゲームをするための24インチ(WUXGA)を使っていますが、1ページに表示できるプログラムの量が増えれば格段に作業しやすいのにと思っています。
何か、秘訣の様なものがあるのでしょうか?

以上、回答いただける点だけでも回答いただけると幸いです。
宜しくお願い致します。

#サンプル
if($test = 1){
 #300行くらい処理が続く
 if($test1 = 1){
  #300行くらい処理が続く
 }
}else{
 #300行くらい処理が続く
 if($test2 = 1){
  #300行くらい処理が続く
  if($test3 = 1){
   #300行くらい処理が続く
  }
 }
}

投稿日時 - 2009-05-04 19:52:25

QNo.4931148

困ってます

このQ&Aは役に立ちましたか?

13人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.9

1つのルーチンを20行程度にまとめられれば、小さな画面でも十分読む事が出来ると思います。
私も20インチのワイドディスプレイを縦型にして(90度傾けて)、高さ1650pxを確保していますが、
エディタのウインドウを分割すると800px以下になりますから、基本は小さな画面で読みやすい事ですね。


if($test == 1){
  &do_test1(); # test1を実行する。というか、コメントが無くても「do test1」という言葉でわかるはず
 if($test1 == 2){
  &do_test2();
 }
}

if($test == 1){
  # test1を実行する
  300行ぐらい続く
  300行ぐらい続く
  300行ぐらい続く
 if($test1 == 2){
  # test2を実行する
  300行ぐらい続く
  300行ぐらい続く
  300行ぐらい続く
 }
}

サンプルとは言え、ある程度きっちり書いておいた方が良いと思います。


クラス(パッケージ)化するのは、
人が見たときには「一定の処理をグループ化する」という意味では、サブルーチンと同じだと思います。
ローカル変数をグローバル変数の用に使える(サブルーチンに引数として渡す必要がない)、変数名の競合対策などとしてはかなり有効な手段だと思いますが、
見やすさという意味では、ほとんど変わらないと思います。

投稿日時 - 2009-05-10 12:06:32

ANo.8

そんな質問者氏には
Damian Conway「Perl Best Practice」(オライリー)
をお勧め.
コードがきれいになってテクニックも身につくでしょう.
Higher Order Perl
もいいかもしれないけど,
日本語訳はありませんし,ちょっと難しいかも
#最後の方の「パーサの作り方」とか「宣言的プログラム」とか
#は圧巻なんだけどそれなりに難しい

さて,分岐が増えてきて混乱するなら
「dispatch table」と呼ばれる連想配列の応用手法が
使えることがよくあります.
分岐先の処理内容そのものを隠蔽してしまうのです.

%case={
1 => sub{ }, # 1に応じた処理
2 => sub{ }, # 2に応じた処理
3 => sub{ }, # 3に応じた処理
}

みたいに書いておいて,実際に処理する部分では
$case{$test}->(引数)
だけ.
#これを発展させていくとPerlのオブジェクトで一般的な
#「連想配列のbless」になったりする

あとは「変数やサブルーチンの名前」を
意味を反映したわかりやすいものにすることも大事.
日本語のローマ字表記はあとで絶対に混乱する.
妙なスペルの省略はしない
(省略するくらいなら,置換などを駆使して
フルスペルで書く)

混乱しない程度にコメントを残しておくのも重要

投稿日時 - 2009-05-10 10:37:06

ANo.7

サブルーチン化しても微妙だなーと思われるようであれば
クラスにしてしまうという方法もあるようです。
詳しくは知らないんですが。

perlも今はオブジェクト指向なったんですよね?
http://www.site-cooler.com/kwl/perl/10.htm

クラスにしてしまえば
プロパティを設定し、必要な場所で実行するだけという
実装部分を隠蔽したような書き方が出来ます。

通常の関数呼び出しでも引き数を与えて、動的な結果は得られるわけですけど、クラス化すると、より多彩な結果を返したり、継承を行うことで、重複するコードを書かずに、変更が必要な部分だけのコードを変更したり、追加したりできるわけです。

クラス内の実装部分では、自分が持つプロパティには自由にアクセスできるし、メソッド(関数)の呼び出しも自由に出来ます。
変数の初期化などは一箇所にまとめられ、実装部分は、提供する機能に集中した、的を絞ったコードを書けます。
よってシンプルになるはずなのです。

以下に良い例が載っているんですが
http://www.site-cooler.com/kwl/perl/10.htm
実装部分に対して、実行部分は3行程度になっています。
参考までに。

継承
http://www.rfs.jp/sb/perl/04/03.html

投稿日時 - 2009-05-06 15:22:39

ANo.6

「実際にどのように分割するか」は, もう本当に「処理を見てみないとわからない」世界です. でも, 基本的には「一言で説明できる範囲」で切っていくんじゃないかな. 「サブルーチン名」がたかだか数単語であることを考えると, それで説明できることが重要.
場合によっては「データの持ち方が適切でない」ということも考えられます.
余談ですが, if/unless/for (foreach)/while/until は式の後ろにつけて「その式だけが対象である」という意味にすることができます. if not = unless なので,
return if not $a;

return unless $a;
は同じ意味で,
if (not $a) { return; }
あるいは
unless ($a) { return $a; }
と同等です.

投稿日時 - 2009-05-05 23:55:01

ANo.5

> 見たことが無い構文ですが、どういった意味になりますか?

return if not $a



if (not $a) {
return
}

と同じ意味です。
確かにググってもすぐに出てきませんね。おかしいな・・・
自分は本で知ったんですが。


> VimやEmacsはまだ使ったことがありませんがお薦めでしょうか?

VimやEmacsのいいところは拡張性じゃないでしょうか。
両方とも細かな挙動の設定や、欲しい機能を自由に追加・変更できたりします。
自分はVimを使っていますが、自分でプラグインを書いたりして機能を拡張しています。

投稿日時 - 2009-05-05 17:53:09

ANo.4

本当にこう書いたんだったら (ある意味) 尊敬するよ....
ふつうはサブルーチンを使うね. 300行もあったらその中には複数の機能ブロックがあるだろうから, それぞれをサブルーチンとして切り出す.
「1回しか実行しないものをサブルーチンにするのは変だ」というかもしれないけど, 個人的にはこの意見こそ変だと思う. 最近では「何らかの機能を持つコードブロックに名前を付けるのがサブルーチンの目的だ」というようにしてる.
とはいえこの if文は明らかにおかしい.
以下余談:
#3 の「視線の移動だけで見える範囲が広いか狭いかは、致命的な差がありますね」には同意するものの, 「15インチ QXGA」のノートPC を使ったりすると 24ドットではつらいのも事実. 36ドットだと, かなりいい感じ.

投稿日時 - 2009-05-05 01:33:26

補足

回答いただきありがとうございます。
全体のサイズが1MBくらいあるため、いつの間にかこんな風になっています。
また、よく使う機能と、時々使う機能は分けて、サブルーチンにしています。
サブルーチンかするという事は、こんな感じでしょうか?

---------
#サンプル
if($test = 1){
 #300行くらい処理が続く
 &suba();
 if($test1 = 1){
  #300行くらい処理が続く
  &subb();
 }
}else{
 #300行くらい処理が続く
 &subc();
 if($test2 = 1){
  #300行くらい処理が続く
  &subd();
  if($test3 = 1){
   #300行くらい処理が続く
   &sube();
  }
 }
}

sub suba(){ 300行くらい処理が続く }
sub subb(){ 300行くらい処理が続く }
sub subc(){ 300行くらい処理が続く }
sub subd(){ 300行くらい処理が続く }
sub sube(){ 300行くらい処理が続く }
---------
とした方が良いということでしょうか?

ただ、この場合でも、1つのサブルーチンに、300行もしくは、それ以上あり、1ページ80行表示するディスプレイを使っているため、まだ、見づらく感じます。
かと言って、このサブルーチンを更に、分解すると、見づらくなりそうです。
どこまで分解して良いものか難しいです・・・
何か、判断基準や、参考になる話などありますでしょうか?

投稿日時 - 2009-05-05 12:18:12

ANo.3

Perl は確かに 「Write only」とか言われます。 書く(プログラミングする)分には良いけど、過去に書いたものや他人が書いたものは読めたものじゃ無いと言う意味でしょう。 私も一理あるとは思います。

しかし、ご質問の件はそれとは別の問題の様ですね。 if の中身が長くなれば、else がでてきても何の if だったか判らないなんて事は、Perl に限らず多くのプログラミング言語に共通の問題です。 対策は、他の回答者さんと同じくサブルーチン化がお勧めです。


> 画面の大きさとプログラムの書き易さには差が無いのでしょうか?

人によって違うと思います。 私は質問者さんと同じで、画面中の文字数・行数は多ければ多い程良い派です。 視線の移動だけで見える範囲が広いか狭いかは、致命的な差がありますね。 一方で、表示文字数を犠牲にしても大きな文字が良いという人も実在します。 それはそれで、尊重しましょうね。

投稿日時 - 2009-05-04 21:03:16

補足

回答いただきありがとうございます。
よく使う機能と、時々使う機能は分けて、サブルーチンにしていますが、
サブルーチン化するという事は、こんな感じでしょうか?

---------
#サンプル
if($test = 1){
 #300行くらい処理が続く
 &suba();
 if($test1 = 1){
  #300行くらい処理が続く
  &subb();
 }
}else{
 #300行くらい処理が続く
 &subc();
 if($test2 = 1){
  #300行くらい処理が続く
  &subd();
  if($test3 = 1){
   #300行くらい処理が続く
   &sube();
  }
 }
}

sub suba(){ 300行くらい処理が続く }
sub subb(){ 300行くらい処理が続く }
sub subc(){ 300行くらい処理が続く }
sub subd(){ 300行くらい処理が続く }
sub sube(){ 300行くらい処理が続く }
---------
とした方が良いということでしょうか?

ただ、この場合でも、1つのサブルーチンに、300行もしくは、それ以上あり、1ページ80行表示するディスプレイを使っているため、まだ、見づらく感じます。
かと言って、このサブルーチンを更に、分解すると、見づらくなりそうです。
どこまで分解して良いものか難しいです・・・
何か、判断基準や、参考になる話などありますでしょうか?

>大きなディスプレイは良いのですが、24インチより大きいものやディスプレイを縦にして使うと、視線の移動だけでもかなりの距離になり、ディスプレイ酔いしそうですし、細かい文字にするとかなり見づらくなります。
スキルの無さをハードで補っている感じ?ですが限界を感じているようなところがあります。
少ない情報量で書ける人は、プログラムの処理全体が頭の中に入っているんでしょうかね?
私も、できることなら、大きな文字で、見やすいプログラムを書きたいと思うのは山々なんですけどねぇ・・・

投稿日時 - 2009-05-05 12:18:38

ANo.2

自分はif文のネストが多くなってきたなーと感じたら
そこの処理をサブルーチン化して

if ($a) {
if ($b) {
...
}
}

という文を

return if not $a;
return if not $b;
...

という風に変えるとかしてますね。
でもだいたいネストしたif文の所の処理は
既にサブルーチン化してあるのでサブルーチンをわざわざ作ったりとか
そういうことを気にすることは少ないような気がします。

ちなみにエディタはVimとかEmacsがおすすめじゃないでしょうか(Linuxでも使えるし
慣れるまで大変かもしれませんが...

投稿日時 - 2009-05-04 20:40:04

補足

回答いただきありがとうございます。
見たことが無い構文ですが、どういった意味になりますか?
少し、ググって見たのですが、いまいちよくわかりませんでした。
補足いただけると幸いです。

また、エディタについては、秀丸を使っています。
確かに、他のOSで使えるというのは良いですね。
VimやEmacsはまだ使ったことがありませんがお薦めでしょうか?

投稿日時 - 2009-05-05 12:32:16

ANo.1

それぞれの処理をサブルーチンにすれば良いのではないですか。

http://www.kent-web.com/perl/chap8.html


エディタも色々ありますよ。
ウィンドウを上下分割して、上と下で、同じファイルの別の場所を表示したり、同じファイルに対して、ウィンドウを複数出したり。

投稿日時 - 2009-05-04 20:00:32

補足

回答いただきありがとうございます。
よく使う機能と、時々使う機能は分けて、サブルーチンにしていますが、
サブルーチン化するという事は、こんな感じでしょうか?

---------
#サンプル
if($test = 1){
 #300行くらい処理が続く
 &suba();
 if($test1 = 1){
  #300行くらい処理が続く
  &subb();
 }
}else{
 #300行くらい処理が続く
 &subc();
 if($test2 = 1){
  #300行くらい処理が続く
  &subd();
  if($test3 = 1){
   #300行くらい処理が続く
   &sube();
  }
 }
}

sub suba(){ 300行くらい処理が続く }
sub subb(){ 300行くらい処理が続く }
sub subc(){ 300行くらい処理が続く }
sub subd(){ 300行くらい処理が続く }
sub sube(){ 300行くらい処理が続く }
---------
とした方が良いということでしょうか?

ただ、この場合でも、1つのサブルーチンに、300行もしくは、それ以上あり、1ページ80行表示するディスプレイを使っているため、まだ、見づらく感じます。
かと言って、このサブルーチンを更に、分解すると、見づらくなりそうです。
どこまで分解して良いものか難しいです・・・
何か、判断基準や、参考になる話などありますでしょうか?

投稿日時 - 2009-05-05 12:35:11

あなたにオススメの質問