新規記事投稿 フォロー記事投稿 記事のキャンセル
From: Yasu.F <uasuf@big.or.jp>
Subject: Re: 不都合な配列の性格に阻まれて
Date: 1999/02/03 05:21:11
Reference: mesh.program/00604

# いつもいつも「詩的な」題名には楽しませていただいているのですが、
# もう少し記事の内容が分かるようなものを付けられたほうがよろしいかと

## といいつつ、適当な題名が思い浮かばないのでそのままです(__)

まず諺をひとつ:

  「プログラムは、設計されたとおりではなく、書かれたとおりに動く。」

2月2日に、三葉工房の管理者さんは書きました。

>始めに,質問するには,どの位の間隔を置いて質問するのが望ましいのでしょうか。

いくら(マニュアルや本やWebなども利用して)調べてみても分からず、どうしても
質問しなければならなくなるごとに、でしょう:-)

> 実は,例のBBSスクリプトの開発で,ユーザーパスワードを利用しての記事削除のプログラム
>を作成していますが,配列の不都合な性格が災いして完成出来ません。

もちろん、これは「あなたにとって」不都合「に映る」というだけですよね。

# あらゆる問題に全て対応できる解決策は存在しません

>簡易スクリプト(配列の性質)

martとかgghとかsdとかdfrとかは何か意味のある単語や略語なんでしょうか。
何のための変数なのか、もっと分かりやすい名前を付けたほうが読みやすいし、
保守やデバッグが楽じゃないかと思うのですが…。

>print "$dfrのはずが$gghの$nrの$dhy\n";

というのをぱっと見て、どういう情報を出力しようとしているのか分かりますか?

それと、ブロック("{" と "}" で囲まれた部分)などは

  sub hoge {
    if ($foo == $bar) {
      &baz(q{I said, "You said, 'She said it.'"});
    }
    else {
      &zot('abc', 'def', 'xyz',
               $something[$foo + $bar] / $anythong{$qux . $quux});
    }
    
    @sorted_array = sort { $a <=> $b } @array if $todo{'sort'};
  }

のように字下げして書くことを強くお勧めします。ブロックの中を全く字下げ
していないと、プログラムの制御構造の流れが追いにくく、とても読みにくいです。

# 少なくとも、前に投稿された例えば「徹底的な…」などのスクリプトを
# 目にしたときは、ぱっと見ではどこからどこまでがひとつのサブルーチン
# なのかすらさっぱり分からず(今でもあまり把握していませんが)、読む気も
# しませんでした

ラクダ本の第2版(背表紙の青いほう)をお持ちなら、いちど「8.4 プログラミングの
書法」(pp.626-)あたりに目を通してみてください。
初版(背表紙の赤いほう)にも同じような内容があったはずですが、いま手許に
無いので何処に載っていたかはわかりません。

>いるので,$dfr=@newmartと言う形で,$dfrの値は,しっかり配列の値の合計値の16と
>出力され,その配列を更に@fft=@newmartと言う記述で@fftに代入して,$dhy=@fft;で

16は「配列の値の合計値」ではなく、単に配列の要素の数ですね。

# 三葉工房の管理者さんにとってはそういう意味なのかも知れませんが、
# 少なくともプログラミング上の一般的な用語としては、両者は違うものを
# 意味します

# ちなみに、何故「17」ではなく「16」なのか理解してます?

>という書き方の様に$martの変換前の状態を文字変換タグで配列の('値','値')に変換して,
>変数のみで配列に代入するだけだと,$ggh=@martと言う形で配列の合計値を算出すると
>値は1で,@mart=@mart,$nr=@martとしても$nrの値は1で,スクリプトの終わりの方の

いくら文字列としてリスト(配列)に見えるように加工しても、依然として
それは単なる文字列にすぎないからです。

# @array = $scalar という式が一体どういうことをやっているのか、
# よ〜く考えてみてください

#   @array = (123, 456, 789);
#   $scalar = @array;
#   @array = $scalar;
#   $scalar = @array;
# とすると @array と $scalar の内容はそれぞれどうなるのか、それは何故なのか、
# よ〜く考えてみてください

同様に、

  $program = "print 1 + 2;\n";
  $program;
  print $program;

は、3 とは表示せずに print 1 + 2; とだけ表示します。「プログラムっぽく
見えるもの」は、必ずしも「プログラム」ではありません。

# しかし、eval($program); は 3 と表示します
# 何故なのかはマニュアルや本やWebをどうぞ

では、どうやって文字列を配列に変換すればいいかは、いしどうさんの投稿を
参照してください(そしてマニュアルや本やWebを探してください)。

>foreach $keymatch(@keymatch){
>($mail,$yourname,$date,$gurl,$hpagename,$coment,$password)=split(/&&/, $keymatch);
>
>if($in{'pawin'} eq $password){
>$keyflag=$keyflag+1;
>last;}}
>だと,ファイルの最下段の記事のパスワード名(mailmg)しか出力せずに,そのパスワード
>名の以外のパスワードは,一致しません。

# これだけだと、例えば @keymatch に何が入っているのか、もとのスクリプトを
# 読まなければ分かりません。必要に応じてそれなりに説明を加えてください

「出力」というのは、何がどう「出力」されるのですか?
引用された部分には「パスワード名」の「出力」と呼べるような処理は含まれて
いないようですが。

$keyflagの値が増えていたら「出力」されたことになるということでしょうか。

>}でプリントアウトしています。foreachで直接プリントアウトすれば,$passwordで
>全て出力されますが,それ以外の方法,例えば$passwordを@***に代入したりすると
>@***は,(mailmg)しか出力しません。

どういうふうに「代入」したのですか?

  @array = $password;

なら、最終的に @array に入っているのは当然ひとつの要素だけでしょう。
代わりにpushなどを使ってください。詳細はマニュアルや本やWebを見てくださいね。

>その様に,ユーザーパスワードを利用しての削除.変更を行うには,どうしても
>$in{'pawin'}($in{'pawin'}は,変更.削除のページのパスワードを入れる記入項目
>から受け取った値)と$passwordの全ての値と一致させなければそれは出来ません。

何故?
$passwordの値は @keymatch の各要素(つまりはファイルの各行)に応じて変化
するのではないのですか?

もしかしたら「一致」とは「比較」のことかも知れませんが、「全ての値」との
「比較」は(foreachループを使って)なされていますよね…。

# そもそも、目的の記事を「パスワード」をキーにして探すという仕様自体が
# とても不自然に感じるのですが…

>後,if((fg == hy)&&(gh<55))とif((fg =hy)の意味はどう言う意味なのでしょうか。

この質問の意味はどう言う意味なのでしょうか。

何が聞きたいのか、この文を読んだだけではさっぱり分かりません。
だいたい if((fg =hy) なんて中途半端な破片(括弧すら対応していない)だけを
ぶった切って引用されても困ってしまうのですが。

質問というものは、他人が読んで理解できるように書かなければ、誰も答える
ことができません。三葉工房の管理者さんに限ったことではありませんが、

  「答えてもらいやすい質問をしてください。」

質問記事の読みやすさは、プログラムの読みやすさより数倍重要です:-)

<PostScript>
#606はPOSTの途中で切れてしまったようです。
投稿完了のページも確認できず、キャンセルコードも分からないので
お手数ですが削除しておいてください(__)>にあさん
</PostScript>