• ベストアンサー

ファイル操作について

別スレ立てているので、ルール違反になっちゃいますかね? もしそうであればゴメンナサイ… sub fanc{ my @array = @_; my $ag = shift @array; my $n1 = 'AAA.csv'; my $n2 = 'BBB.csv'; my $n3 = 'CCC.csv'; my $n4 = 'DDD.csv'; my $n5 = 'EEE.csv'; ・ opendir(DIR, "C:/Program Files/Apache Group/Apache2/cgi-bin/test");my @pairs = readdir(DIR); close(DIR); if($ag == 1){@files = grep(/$n1/,@pairs); } if($ag == 2){@files = grep(/$n2/,@pairs); } if($ag == 3){@files = grep(/$n3/,@pairs); } if($ag == 4){@files = grep(/$n4/,@pairs); } if($ag == 5){@files = grep(/$n5/,@pairs); } if($ag == 6){@files = grep(/$n6/,@pairs); } ・ $dfile1 = $files[0]; open(IN,"$dfile1") or exit; chomp(my $row01 = <IN>); chomp(my $row02 = <IN>); chomp(my $row03 = <IN>); chomp(my $row04 = <IN>); chomp(my $row05 = <IN>); chomp(my $row06 = <IN>); ・ close(IN); my @col01 = split(/,/, $row01); my @col02 = split(/,/, $row02); my @col03 = split(/,/, $row03); ・ ・ こういったコードをもっと短く、書くやり方を知りたいです。 grepでヒットするのが複数の場合もあるため、当初はForeach文とフOpenで配列@filesに入った ファイルを全て展開して、配列、又は変数に格納しようと思ったのですが、どうやって複数の配列をOpen関数で扱えばいいのか解りません。 もしそうでなければ、現在は一つのファイルに対しての処理ですが、残ったファイルに関しても関数を回す方法があれば、ご教授願えませんか??あ、あと、CODE(xxxxxx)ってなんのことでしょう?

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

> サブルーチンの演算子は何かの布石なのでしょうか? サブルーチンの演算子とは何を指しておっしゃっているのでしょうか? add/subtract等のサブルーチンで使っている+、-等の演算子ということであれば 特に深い意味はありません。 短く書けて分かりやすい例を思いつければよかったんですが。

polalis
質問者

お礼

sakusaker7様、ご回答ありがとうございます。 リファレンス…多少は砕けましたが、やっぱり難しいです。。。 多次元配列に出来るとか、そういう部分での文献を色々読みましたが、自分で使いこなせるように ならないと、多分完全に理解は出来ないですよね。 色々、ご丁寧にありがとうございました。 これから勉強する課題にいたします。

すると、全ての回答が全文表示されます。

その他の回答 (4)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

> この結果値は、どうやって表示したらいいのですか? 例に出したように、dereferenceしてやればいいです。 ただし相手はサブルーチンなので、引数の数があってないとダメですけど。 そもそも意図しないでリファレンスが返ってくるほうが問題ではないでしょうか? > 通常は、どうやって参照するものなんですか? &$fnc_ref; とか $fnc_ref->(); のようにすると呼び出しになります。 #これは引数がない場合 > なんのために使うのかとか、色々お手数でなければリファレンスについてご教授ください。 サブルーチンへのリファレンスであれば、 Cでいうところの関数ポインタみたいな使い方をします。 あとは多次元配列を実現するためとか、オブジェクトを作るためなんかに リファレンスは使われます。詳しくは perldoc perlref で。 あまりいい例が思い浮かばなかったのですが use strict; use warnings; sub add { my $lhs = shift; my $rhs = shift; $lhs + $rhs; } sub subtract { my $lhs = shift; my $rhs = shift; $lhs - $rhs; } sub multiply { my $lhs = shift; my $rhs = shift; $lhs * $rhs; } sub div { my $lhs = shift; my $rhs = shift; $lhs / $rhs; } sub modulo { my $lhs = shift; my $rhs = shift; $lhs % $rhs; } my @fn_table = (\&add, \&subtract, \&multiply, \&div, \&modulo); my $arg1 = int(rand(100))+1; my $arg2 = int(rand(100))+1; print "arg = $arg1, $arg2: "; foreach my $fnc_ref (@fn_table) { print $fnc_ref->($arg1, $arg2), ", "; #print &$fnc_ref($arg1, $arg2), ", "; }

参考URL:
http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.html
polalis
質問者

補足

sakusaker7様、ご回答ありがとうございます。 文献もバッチリ読みました…が、私にはいまいち理解が苦しいです。 スミマセン…それから上記のコードなのですが、サブルーチンの演算子は何かの布石 なのでしょうか? せっかく教えていただいてるのに、申し訳ないのですが解説も頂けると幸いです。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#2>@filesをshiftしていって それでもいいですけど、foreach でいいような・ あと、$rownn=<IN> も @rows=<IN> でいいような気がします。 #2>原因は、最終行に"1,3,4"や"1:4"のようなデータが入っているから あれって、"1,3,4"や"1:4"は、調べるべきパターンで、最終行には返すべき結果が、入っているという前提ですよね。 最終行が、そういうパターンの場合もあるなら、 最終行のそういう変換はしないというように変更しないといけないですね。 単純にループでデータの読込&変換をやっていますから、 そのままでは、ループの中で最終行という判断はできませんから、 ループでデータを読み込むのではなくて、 いったん、全部のデータを読み込んでしまってから、 最後のデータ行を除く変換を行うように書き換えればいいと思います。

polalis
質問者

補足

>あと、$rownn=<IN> も @rows=<IN> でいいような気がします。 なるほど…やはり、Foreachの使い方をもう少し勉強しないといけませんね。。。 ここでやりたいことは、ファイルの3列15行の数値データなんですが、 各行の3列目を2列目で割る という処理をしていて、なんとなく最初に配列に入れるより変数から splitして配列に入れたほうが 固体になって計算しやすいかな…と思ったもので。 >ループでデータを読み込むのではなくて は、 open(IN, $dfile) or exit(-1); while(<IN>) { のことですよね?? >単純にループでデータの読込&変換 は、 quotewords("," => 0 , $_); だったり if(index($field, ":") >= 0) { のことでよろしいんですよね? う~ん、やっぱり難しいです。本は結構読んでるですが、なかなか一朝一夕にはいきませんね。。。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

このような場合には、配列やfor で処理することを考えましょう 例えば、 my @n = ('AAA.csv','BBB.csv','CCC.csv','DDD.csv','EEE.csv'); とすれば、 if($ag == 1){@files = grep(/$n1/,@pairs); } if($ag == 2){@files = grep(/$n2/,@pairs); } … は、 @files = grep(/$n[$ag-1]/,@pairs); とできると思います。

polalis
質問者

補足

BLUEPIXY様、お返事遅れました。せっかく教えてくださっているのに、ゴメンサイ… アドバイスありがとうございます。 長々しく書いていた、コードが少しスッキリしました。 Open関数で扱うファイルが複数の場合は、やはり一つ目を読んだ後に@filesをshiftしていって $dfile1 = $files[0];をif文等でデータ無しまで、評価すればいいですよね? ところでBLUEPIXY様に直接お聞きしたかったのですが、以前教えて頂いた、絞り込む関数(squeezed) で質問なのですが、 >CODE(xxxxxx)ってなんのことでしょう? は、このサブルーチンの戻り値で出てしまうものなんです。 原因は、最終行に"1,3,4"や"1:4"のようなデータが入っているからだと思うんですが この値を、どうにか返せないものでしょうか? CODE(xxxxxx)は、どうやって参照すればいいのですか?? 本当に何度もお手数をおかけして、申し訳ありませんがご教授下さい。

すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

とりあえず > CODE(xxxxxx)ってなんのことでしょう? についてだけ。 コードのリファレンスを普通の変数のように表示しようとすると出る奴ですね。 $code_ref = sub { print "hello, world\n"}; print $code_ref; print "\n"; &$code_ref; 実行結果: CODE(0x1626160) hello, world

polalis
質問者

補足

sakusaker7様、遅くなりましてゴメンナサイ。 回答ありがとうございます。 なるほど、コードのリファレンスを普通に見ようとすると出るもの なんですか。。。 #2のBLUEPIXY様にも、お尋ねしてしまっているのですが、この結果値は、どうやって表示 したらいいのですか? 通常は、どうやって参照するものなんですか? 当方Perl初心者の為、いまいちリファレンスの感じがつかめません。 なんのために使うのかとか、色々お手数でなければリファレンスについてご教授ください。

すると、全ての回答が全文表示されます。

関連するQ&A