プロが教える店舗&オフィスのセキュリティ対策術

メールヘッダーの解析をリファレンスを使っているが、上手く出来な
い。理由は、無名配列を使っていない為に常に最後のデータでで上書き
される為。ここで、無名配列を使った方法が良く分からない。

メールヘッダーの構造は下記の通り。
① 最初にヘッダー、次がデータの順で構成されている。
② ヘッダーの開始は、Return-Path:から始まる。
③ ヘッダーの終わりは、空行。/^$/
④ データの開始は、ヘッダーの終わりの空行の次の行から開始する。
⑤ データの終わりは先頭のピリオドのみのデータ /^\.$/

上記の構成で、ヘッダーを配列@headerにデータを@dataに入れる。
ここでは、常に最初は@headerに次は@dataに交互に格納される。

@headerと@dataには、複数行のデータを配列のリファレンスとして格納
する。今の状況は夫々@headerと@dataには確かにリファレンスは格納さ
れているが。無名配列を使っていない為に、常に最後のデータしか格納
されていない。

ここでは、@headerの要素の@header_lineと@dataの要素の@data_lineへ
のデータの格納が不味い。ここの所をどの様にして無名配列を使ったら
良いのか、指摘をお願いします。

宜しく回答願います。

なお、今の不具合が発生をしているperlのソースを掲載します。これは
無名配列を使っていません。そこから、上記のバグが発生をしていま
す。

このソースを無名配列を使ったやり方に変更をしたい。宜しく回答願い
ます。また、これに関しては一番簡単な方法と言うのは、use strrict
宣言をしてから、夫々の@header_lineと@data_lineにmyの宣言をすれば
良いとは分かっていますが。

それ以外の方法での解決をお願いします。この手の問題と言うのは、私
は余りリファレンスを使う事が無いので。これを機会にして一つの定石
にしたいと思っていますので。宜しくお願いします。

長々と長い質問になりましたが宜しくお願いします。

下記の問題のperlのソースを掲載します。宜しくお願いします。

@header=();
@data=();
while(<>){
if(/^Return-Path:/){
$flag="header";
@header_line=();
$tmp=join("->",$.,$_);
push @header_line,$tmp;
next;
}

if($flag eq "header"){
if(/^$/){
$tmp=join("->",$.,"<blank>\n") ;
push @header_line,$tmp;
push @header,\@header_line;
$flag="data";
@data_line=();
next;
}
}

if($flag eq "data"){
unless(/^\./){
$tmp=join("->",$.,$_);
push @data_line,$tmp;
next;
}else{
$tmp=join("->",$.,$_);
push @data_line,$tmp;
push @data,\@data_line;
next;
}
}
}

for $i(0 .. 2434){
@ref_header=@{$header[$i]};
print @ref_header;
@ref_data=@{$data[$i]};
print @ref_data;
}

質問者からの補足コメント

  • うーん・・・

    いつも、回答をして頂き有難う御座います。

    回答は、唐突に質問者が使っていないコードでは無くて
    質問者の使っている言葉での説明をお願いします。

    唐突な言葉と言うのは、質問者の理解には何の役にも
    立ちません。質問者の視線に合わせての回答を願います。

    そうしないと折角の努力が実りません。大穴の空いたバケツ
    に水を注ぐ様な物です。私が逆の立場で回答をする立場で
    回答をする場合は、質問者が使っている言葉で説明をする
    様、努めますが。

    今後とも宜しくお願いします。
    言葉だけで理解をさせ様とする所なので中々難しい所で
    は有ります。

      補足日時:2017/03/09 20:55
  • うーん・・・

    二つ目は、@headerの要素には無名配列の要素が入っている。この時の
    リファレンスは毎回に異なる値が入っている。然し、毎回異なる値のリ
    ファレンスが入っていたとしても、無名配列の中の要素その物はつねに
    同じ値が入っているのだから。結果として最初のpush
    @header,\@header_lineとやっている事は同じではないのかと。

    と言う事を私は何回も記憶領域と言う言葉を使って切実に訴えての質問
    をしていると思いますが。何故に分かろうとしてもらえないのか。ここ
    にも当然に、それなりの理解の違いが横たわってはいますが。
    ...続く。

    No.3の回答に寄せられた補足コメントです。 補足日時:2017/03/10 07:24
  • うーん・・・

    それは分かりますが。私が言いたかった言葉と言うのは。分かってもら
    えたでしょうか。私が立場を代えて、この質問者の立場から一転して回
    答者の立場になったならば。ここは、必らず質問者の言葉を使って説明
    をしないと質問者は立腹をすると言う事は目に見えると思いますが。

    私は前回にも言ったんですが。この世の大半は知らない人の世界で動い
    ている。だって全てを知っている人はいないわけですから。その一部で
    しか持ち合わせてはいないですから。だから、唐突にお酒の成分の話を
    した時に「蛋白質」の話がどうのこうのと言っても、トナーの導電性と
    かの話をされても知らない人は知らない。知っている人は、息を吐く様
    に知っている。

    そこから、質問者もこれくらいは知っていると言う事での安易な回答は
    それこそ誤解と曲解に油に火をを注ぐ事になる。
    ...続く。

      補足日時:2017/03/10 07:30
  • うーん・・・

    長くなりましたが。気を悪くされたらごめんなさい。往々にしてこの様
    な事は有り得ると思います。当然にこの様な事は黙って言わない万が大
    半だとは思いますが。

    私は言います。だって、改善をしないのですから。私は、現実世界の中
    でもかなりにこの様な事はします。今後の回答に役立ててほしいからで
    す。

    宜しく、この趣旨を理解をされての回答をお願いします。
    ...終わり

      補足日時:2017/03/10 07:31

A 回答 (4件)

$r = [] ;



{my @ary = () ; $r=\@ary ;}
と(ほぼ)同じです。

$r = [1,2,3] ;

{my @ary = (1,2,3) ; $r=\@ary ;}
と同じです。

と、考えれば
$r = [ @list ] ;

{my @ary = (@list) ; $r=\@ary ;}
と同じ、ということになります。

このときの、 @ary と @list の関係がどうなっているか、よく考えてみましょう。
print \@ary , \@list ;
とかやってみてもいいでしょう

http://perldoc.jp/docs/perl/5.14.1/perldata.pod# …
が参考になります。


> use strrict 宣言をしてから、夫々の@header_lineと@data_lineにmyの宣言

use strrict と my は直接関係はありません。

http://perldoc.jp/func/my
myは「ローカル変数」を定義するためのものです。
use strict とは関係無く利用できます。

http://perldoc.jp/docs/perl/5.12.3/strict.pod
use strict あるいは use strict "vars"; は、未定義の変数を使えないようにするもので、
結果 my を使うことが多くなりますが、他の手段の方が好ましいこともあります(our とか)


「よいプログラム」の作り方として
・グローバル変数は使わない
・ローカル変数も、できるだけ有効範囲を狭くする
というのがあります。

Perlでも
・そのままではグローバルになるので、my を着ける
・my を忘れないようにuse strict を使う
というのが、昨今の流れです。
    • good
    • 0
この回答へのお礼

有難う御座います。

いつも思うのですが。コンテキストが何かずれている感じがします。
情報のアウトラインと言う言葉をご存知でしょうか。

ハイコンテキストモデル、ローコンテキストモデルが有りますよね。
人に言うのは簡単ですが。いざやるとなると、中々難しいですね。
人に説明をすると言うのは当人が理解をするのとは違う世界です。

名選手、必らずしも名監督ならずです。
野球の王選手と長嶋監督がその端的な現れですが。

コードでの回答は、コードに有らず。
説明での回答は、ここぞとばかりのコードに指す。
一番説明をして欲しい所は、ここぞとばかりにぼかす。

この場合の私の質問の趣旨を理解をしての回答なのでしょうか。
回答を貰って置きながら小言を言いまして済みません。

人に分かる様に説明をする為には、良く聞いて要点の整理が必要です。
私は、一体何を質問をしたのでしょうか。

有難う御座いました。

お礼日時:2017/03/09 20:41

Return-Path の処理で、@header と @data に無名配列を追加すれば、@header_line と @data_line は必要ないと思います。

以下は Return-Path 行の処理の一例です。残りの header と data も少しコードを修正すれば、直接無名配列に格納することができます。

if(/^Return-Path:/){
$flag="header";
push @header, [];
push @data, [];
$tmp=join("->",$.,$_);
push @{$header[-1]},$tmp;
next;
}
    • good
    • 0
この回答へのお礼

有難う御座います。

/^return-Path:/でヘッダーが始まる。それを、$flag="header"として
記録する。ここ迄は分かります。然し、次のpush @header,[]と言うの
が分かりません。この時の@headerには何が入るのでしょうか。

また、おなじ事ですが。push @data,[]と言うのが分かりません。と言
うのは、今のじょうたいと言うのはヘッダーなので@dataとは関係は無
いと思うのですが。

また、この時のpush @data,[]と言うのも@dataには何が入るのか分かり
ません。

回答の中で、一番分からないのが。最後のpush @{$header[-1]},$tmpで
す。$tmpの内容は分かります。然し、@{$hrader[-1]}と言うのが何なの
か。分かりません。

すみません。分からない事ばかりですが。私の理解はそんな物です。す
みません。教えて下さい。多分に、その辺が今回の問題の肝の様な感じ
がします。

宜しくお願いします。

お礼日時:2017/03/10 18:02

@foo = @bar;


でも
$foo = [@bar];
でも, @bar の全ての要素が改めてコピーされる (と思っていい).

で「質問者の使っている言葉での説明」ということだが, ではまずあなたが
push @header,\@header_line;

push @header,[@header_line];
のそれぞれの動作をどのように理解しているのか, 適切なマニュアル等を引用しながら説明してくれないかな. 「質問者の使っている言葉での説明」を求めるということは, 逆にいえば「質問者の使っている言葉」について問われれば委細漏らさず「これでもか」というくらい厳密に説明してくれるってことだよな?
この回答への補足あり
    • good
    • 0
この回答へのお礼

有難う御座います。

私が前回の時に使った言葉の中で繰り返し使っている言葉と言うのが有
りますよね。その言葉で説明をして欲しかったのですが。それは、必ら
ずしも多分に回答をされて全くごく当り前に理解をされている方に取っ
てはりふぜんかも知れませんが。然し、ここではその言葉を使って説明
をしてほしかった物ですから。

私は、繰り返し何回も同じ言葉を使って質問をしています。また、その
言葉を使って回答をしてもらわないと私は納得し難いです。

それは、記憶領域と言う事です。私は何回もそこでは繰り返し
push @header,\@header_line;

push @header,[@header_line];
を使っていますよね。

だから、当然にこの言葉を使っての説明を求めている訳です。何故に唐
突にこの言葉以外での説明をするのでしょうか。私は、何回もその言葉
で切実に訴えての質問をしていますよね。何故、理解をしようとしない
のでしょうか。

一般的な話題でも確かに言おうとしている事は分かリますよ。然し、
もっと的確に手短に相手に伝えるにはそれが直球で伝わると思うのです
が。

回答者と質問者の間には、相当の溝が有ると言う事を先ずは理解をして
ほしいと思います。質問者は回答者と全く違うスキルの壁が有ります。

私が前に質問をした内容を一言で言うと。
push @header,\@header_line;

push @header,[@header_line];
の違いは何ですかと言う事ですが。

それを記憶領域と言う言葉を使って説明を求めていると言う事がどうし
て分かってもらえないのだろうか。

だって、当然にその様なネットでの情報を得てもこの様に理解をしてな
いのですから。かなりに誤解と曲解をしているのですから。必りにスキ
ルに難癖が有るのですよ。

また、蒸し返す様で質問をしますが。push @header,\@header_lineは、
@headerの要素には@header_lineのリファレンスが入っている。
...続く

お礼日時:2017/03/10 07:20

一番簡単なのは


push @header,\@header_line;

push @data,\@data_line;
をそれぞれ
push @header,[@header_line];

push @data,[@data_line];
に変えること.
    • good
    • 0
この回答へのお礼

有難う御座います。

push @header,\@header_lineとpush @header,[@header_line]の違いが
今一つ分かりません。@header_lineと言うのは、同じ変数を使いまわし
ているので最初の記憶領域は同じなので私の今の処理は常に上書きされるの
が原因で、最終結果は最後の処理の内容が格納されます。

これは、push @header,[@header_line]にしても@header_lineその物は
同じ記憶領域を使っているのでpush @header,\@header_lineと同様の現
象になると思っていたのですが。

私のどの部分に理解が足りないのでしょうか。私が思うには例えこの場
合は無名配列にしても中身の@header_lineその物は常に同じ値を示して
いるので意味が無い様に思うのですが。

実際は、そうでは無くてきちんと夫々違う記憶領域を確保しています。
私は無名配列は単にその都度違う記憶領域を確保するだけで有ってその
要素に付いては別物だと思っていたのですが。

その中身についても違う記憶領域を確保すると言う事でしょうか。済み
ません。もうこのコードが動くと言う事は出来たので。今度は中味に付
いて説明をお願いします。

宜しくお願いします。

お礼日時:2017/03/09 09:47

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!