![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
KENTさんの作ったメールフォームのコードをフォローしています。
Clip Mail v1.1です。
http://www.kent-web.com/data/clipmail.html
その中で、メールフォームから送られてきたデータを取り入れるサブルーチンに関する質問です。
undef(%in);
$in{$key}.="\0";
$in{$key}.=$val;
最初の
undef(%in);
はサブルーチン中の冒頭にあり、残り2行とはかなり離れた位置にあります。
これまで私がこういうコードを書く場合、
%in;
$in{$key}=$val;
と書いてきました。この他、変数の宣言にはourとかmyとか付けてますけど、KENTさんがこのプログラムを書いた当時はmyはともかくとして、ourを付けることはあまり普及していなかったのではないでしょうか。
さて、C言語などだと変数を用いる前に宣言だけでなく初期化も行っていないといけないわけですが、Perlの場合は初期化されていない変数はundefとして自動認識されます。
undef(%in);
と、私がやっているような
%in;
の違いは初期化もきちんとしているか、ただ宣言だけで初期化はPerlにお任せしているかの違いです。Perlの仕様上はどちらでもいいでしょう。
分からないのは残りの2行のコードです。
undef(%in);
でキチンと初期化してある変数に対して、まず
$in{$key}.="\0";
とします。なんでNULL文字なんか入れないといけないのでしょう。それも単純に
$in{$key}="\0";
ではなくて、
$in{$key}=$in{$key}."\0";
です。
更に3行目で
$in{$key}.=$val;
とするわけですが、こんな2行かけた代入を行わなくても、私がこれまでやってきたように
$in{$key}=$val;
で実用上の用は足りると思うのですが・・・
1行目は何となく分かるんです。変数の初期化は、Perlに自動認識の機能があるのを知っていても、他の言語を知っている方は、やはり言語任せに出来ないのではないでしょうか。
残りの2行のコードも多分そんなところだと思います。実用上は私のやり方で足りると思うので。ただC言語なんかでもこんな代入の仕方をしているのを私は見たことがないし、まあ、こんな代入の仕方をしないといけない言語もあるのでしょうが、ではその言語でこのやり方をせずに私がやるような方法を取った場合、どんなエラーが出るのでしょう。
どなたか分かる方、教えていただけないでしょうか。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
NULL文字を入れているのって、同じフォーム名を複数使った場合の区切り文字ってことはないですか?
ソースコードを細かく追ったわけではないので違っていたらごめんなさい。
よくフォームのデコード処理でNULL文字は区切り文字として使われることが多いので。
参考になりましたら。
このコードはフォームデータをCGI側で受け取る際に使っています。
普通、フォームデータはinputタグごとに一つずつname値なりid値なりを設定するので、フォームデータから得たキーと値をそれぞれ$key、$valに格納して、さらにそれを
$in{$key}.=$val;
とすると、この式は
$in{$key}=$val;
と同意になります。
しかしinputタグのtype値がcheckboxの場合など複数回答がありうる場合は、その設問でname値なりid値を同じくしておいた方が便利な場合があります。この場合に、
$in{$key}=回答1\0回答2\0回答3・・・
のようにするために、
$in{$key}.=$val;
としていました。
ありがとうございます。
No.2
- 回答日時:
> undef(%in);
>と、私がやっているような
> %in;
>の違いは初期化もきちんとしているか、ただ宣言だけで初期化はPerlにお任
>せしているかの違いです。
$in{$key}.="\0"; はおいておいて、
%in;
では変数の初期化は行われません。変数の初期化を行うなら
%in = ();
ですね。
下記を実行してみてください。
use strict;
use warnings;
use Data::Dumper;
my %in = ( a=>1, b=>2);
print Data::Dumper->Dump( [ \%in ] );
%in;
print Data::Dumper->Dump( [ \%in ] );
undef %in;
print Data::Dumper->Dump( [ \%in ] );
exit;
この回答への補足
6行目のように、ただ
%in;
と宣言しただけでは、前の%inを引きずってundefに初期化されないんですね。
この場合の6行目は宣言と言えるかという問題もあります。結果的に何もしない式を書いただけとも言えます。このように実際のコーディングの中で、コーディングする方は宣言したつもりが、Perlの方はそうではない解釈をしている可能性もあるわけで、そこらへんが自動認識の怖さですね。
undef(%in);
としておけば、そこらへんの曖昧さがなくなるということですね。
ありがとうございます。
No.1
- 回答日時:
$in{$key}.=$val;
$in{$key}=$val;
この二つが同じにみえるのですか?
これが同じにみえるなら
$a += 1;
と
$a = 1;
が同じということになります.
KENT氏は,\0をきっと
「値のセパレータ」
として使ってるんでしょうね.
この回答への補足
アドバイス、ありがとうございます。
セパレータとして使うのであれば、同じキーのin変数に何度もその時々の$valが代入されなくてはいけません。でもそれぞれのキーで件の2行のコードが行われるのは1度きりです。もっともコード自体はforeach文で何度も廻していますけど、その時々でキーが違います。
そうすると、
$a += 1;
と
$a = 1;
が同じということになってしまうような。
つまり当初$aはundefで、Perlの場合、$aを数字として扱う場合は0と自動認識されますから、一度だけ
$a+=1;
を行った結果は1であり、
$a=1;
と同じ意味になってしまうのではないでしょうか。
同じくたった一度きり$valを代入するのであれば、
$in{$key}=$val;
でいいような。
ちょっとNULL文字の意味が良く分からないのですが、今問題にしているプログラムはメールフォームなので、後々全てのデータを一繋ぎにして送信を掛けるような仕様になっているのかも。その際にはNULL文字が仰るようにセパレータになるのかもしれません。
でもとりあえず、それぞれのキーで
$in{$key}.="\0";
$in{$key}.=$val;
は一度しか行われていないので、私の持っている知識だとこの2式は
$in{$key}="\0".$val;
と同意です。
それと、このプログラムではデータをメール形式に直すサブルーチンとしてmimew.plを用いていますが、私の持っている別の本にあるサンプルプログラムのメールフォームでは、同じくmimew.plを用いていますが、mimew.plにデータを渡す前処理として個々のデータの前にNULL文字を加えるなんてしていないんですよね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 英語 提示した名言について(並列表現の文法規則) 4 2023/06/02 09:41
- 英語 私の車は、購入してから7年目になるが、これまでに車検を3回受けた。の英訳 11 2022/06/13 03:39
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- JavaScript 変数宣言と初期値代入の場所について 3 2022/10/31 19:09
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- その他(プログラミング・Web制作) ColabでのPytorchのエラー 1 2022/11/19 20:51
- Java Java 南京錠 2 2023/02/04 11:46
- その他(プログラミング・Web制作) python 3.10で 同じlistに同じ構文で同じデータ代入した結果が異なる現象発生 7 2022/06/18 11:08
- その他(プログラミング・Web制作) atcoder python コードへの助言 2 2022/08/12 15:31
- 英語 Osteogenesis in group B and C were significantly l 2 2022/03/24 05:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
foreach 回数制限
-
Application.ScreenUpdating = ...
-
JSONで文字列が長い時
-
セレクトメニューで2つの項目...
-
メモリをアドレスを直接指定し...
-
文字の横にプルダウンを表示さ...
-
テーブル内でドロップダウンメ...
-
[Ruby] irbにおける文字化け
-
数値かどうかの判定方法
-
実行時エラー 3020の対策
-
エクセルVBA シート名の部分一...
-
変数名に変数を使用
-
formで特定のinputを送信しない...
-
phpでボタンを押したときに変数...
-
Python - Excel で Webからデー...
-
文字のカラーとフォントの指定...
-
子windowsからsubmit()後にclos...
-
【至急!!!】python言語で本を見...
-
FindFirst を複数条件で検索
-
16進の10進変換について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CLispのloop内の挙動について
-
Perlで自分自身の関数名を知る...
-
Net::Telnetでタイムアウト時間...
-
print <<"_HTML_"の中でサブル...
-
Rubyのgets関数について
-
10進数→2進数
-
CGI初心者です
-
Perlで複数の値を返す良い方法...
-
作業域が消える(ように見える)
-
検索機能の作成で困っています
-
Pythonのマルチプロセスでの並...
-
ハノイの塔の問題で困っており...
-
LISPで連想配列の操作?
-
PERLの「!=」と「=~」 or...
-
PerlでCabochaを呼び出すには(...
-
foreach 回数制限
-
シェルでawkを使い行数を取り出...
-
Wコロン
-
HASH(0xほげほげ)
-
プロトタイプ宣言のワーニング...
おすすめ情報