WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:リファレンスの使い方(Perl5)

ひよこ [MAIL] [WriteDate : Sun Apr 22 17:47:02 2001]

どうも初歩的な事でつまづきました。(^^;

引数をセットしてサブルーチンを呼び、グローバルな配列に入ったデーターを戻したいのです。

$data[0]="aaa,bbb,ccc,10,20,30";
$data[1]="ddd,eee,fff,40,50,60";
以下@dataにデーターがある。
$pos1 = 1;
$pos2 = 3;
この場合に、サブルーチンで
@dt = split(/","/,$data[$pos1]);
$ans = $dt[$pos2];
と言う感じでデーターを抽出し、呼び出しもとへ$ansを返したいのですが
リファレンスの使い方が今一理解できていません。

もう1つ
@dtもsplitなど使わないで直接$ansを引き出す方法もあるのでしょうか?
それが出来ればサブルーチンを使わなくても良さそうなのですが。
どちらにしろリファレンス、デリファレンスの使い方を教えて下さい。
#ちょっと情けなくて落ち込み気味(^^;


andi [WriteDate : Sun Apr 22 18:51:51 2001]

> @dt = split(/","/,$data[$pos1]);

リファレンスどうこうじゃなくて、/","/→/,/ではないですか?


andi [WriteDate : Sun Apr 22 18:53:07 2001]

> 直接$ansを引き出す方法もあるのでしょうか?

$ansが何を指しているのかが曖昧です。


ひよこ [MAIL] [URL] [WriteDate : Sun Apr 22 19:48:36 2001]

> リファレンスどうこうじゃなくて、/","/→/,/ではないですか?

split(",",$data[$pos1]); の間違いでした(^^;


$pos1 = 1;
$pos2 = 3;
$ans ->&dd(\$pos1,\$pos2);  #これじゃおかしいですよね。
???

sub dd{
 my(@aa)=@_;
 my $ans="";
 @dt = split(",",$data[$aa[0]]);
 $ans = $dt[$aa[1]];
 return \$ans;
}

> $ansが何を指しているのかが曖昧です。
多次元配列として
$ans=$data[0][3];
の様にアクセスできないかなぁ? と言う意味です。
現在の@dataの状態では$data[0][3]は何も出てこない(nullかな?)


R.M [WriteDate : Sun Apr 22 21:24:39 2001]

$pos1 = 3;
$pos2 = 3;
$data[0] = newArray("aaa,bbb,ccc,10,20,30");
$data[1] = newArray("ddd,eee,fff,40,50,60");

print $data[$pos1][$pos2];

sub newArray{local(@a)=split(/,/,$_[0]); return \@a;}

リファレンスの基本的なことを掴んでいらっしゃらないようで……


R.M [WriteDate : Sun Apr 22 21:26:44 2001]

あ、 $pos1 が...


ひよこ [MAIL] [URL] [WriteDate : Sun Apr 22 22:13:01 2001]

> リファレンスの基本的なことを掴んでいらっしゃらないようで……
いや〜、仰せの通りでして、まだperlの1%も理解してないかもしれません。(^^;

> $data[0] = newArray("aaa,bbb,ccc,10,20,30");
> $data[1] = newArray("ddd,eee,fff,40,50,60");
>
> print $data[$pos1][$pos2];

便宜上$data[0] = .. の様に書きましたが、CSVファイルからすでに@dataへ読み込まれていまして
print $data[0] とかで読み出しは出来るんですが、print $data[$pos1][$pos2]; では何も出力されないんです。
たぶん配列の仕組みさえ理解してないのかも・・
もとのFILEから
open(FILE, "$filename");
@data = <FILE>
として入れ込んだものです。

> sub newArray{local(@a)=split(/,/,$_[0]); return \@a;}

あちこちでサブルーチンをコールするので、
無名サブルーチンのでの方法は考えていませんでした。
それと、複雑な計算後、答えを返したい部分もあるのでどうしても
リファレンスを理解してないといけないと思ってがんばってますが
まだまだ頭は混線中です(^^;
もう少しがんばってみます。



R.M [WriteDate : Mon Apr 23 05:00:28 2001]

単純にこんなのとか

print &getData($pos1,$pos2);

sub getData{
 my(@a) = split(/,/,$data[$_[0]]);
 return $a[$_[1]];
}

無意味に凝ってみてこんなのとか(こっちは自信無し)

$hoge = new HogeData(\@data);
print $hoge -> getValue($pos1,$pos2);

package HogeData;
sub new {
 my $self = {};
 bless $self;
 $self -> {"ref"} = pop;
 return $self;
}
sub getValue {
 my $self = shift;
 my $csv = ${$self -> {"ref"}}[$_[0]];
 return (split(/,/,$csv))[$_[1]];
}

ちなみに
> sub newArray{local(@a)=split(/,/,$_[0]); return \@a;}
これは「無名」ではありません


謎の人R [WriteDate : Mon Apr 23 05:19:55 2001]

>多次元配列として
>$ans=$data[0][3];
>の様にアクセスできないかなぁ? と言う意味です。

正直自分でもやったことがない分野なのですが(汗)、勉強として、『プログラミングPerl』片手にいろいろやってみましたので、ご参考になれば幸いです。
☆「リストのリストを操作する」っていうあたりです
☆「perlの1%も理解してないかもしれません」ということなので、いろいろ変化を加えてあります(笑)


【test.plの内容】
=begin
"test.dat"に入っているデータ
aaa,bbb,ccc,10,20,30
ddd,eee,fff,40,50,60
=cut

$file = "test.dat";
open( FILE, "$file" ) or die "can't open $file: $!";
@log = <FILE>;
close( FILE );

#その1
foreach $log ( @log ){
    chomp( $log );    #改行除去
    @tmp = split( /,/, $log );
    push( @data, [ @tmp ] );
}
print "1--------------------\n";
print "$data[0][0],$data[0][3],$data[0][5]\n";
print "$data[1][0],$data[1][3],$data[1][5]\n";

#その2
$n = 0;
foreach ( @log ){
#$logなど未指定の場合、$_にデフォルトで格納されるが、表記を省略できる
    chomp;
    $data2[$n] = [ split(/,/) ];
    $n++;
}
print "2--------------------\n";
print "$data2[0][0],$data2[0][3],$data2[0][5]\n";
print "$data2[1][0],$data2[1][3],$data2[1][5]\n";

#その3(おすすめ?)
@data3 = &test( @log );
print "3--------------------\n";
print "$data3[0][0],$data3[0][3],$data3[0][5]\n";
print "$data3[1][0],$data3[1][3],$data3[1][5]\n";


#番外?シンプルに
print "4--------------------\n";
print &test2( 0, 0 ), "," ,&test2( 0, 3 ),",",&test2( 0, 5 ),"\n";
print &test2( 1, 0 ),",",&test2( 1, 3 ),",",&test2( 1, 5 ),"\n";


#番外2?自分でもよくわかっていない(苦笑)
$data5 = test2;
print "5--------------------\n";
print &$data5( 0, 0 ), "," ,&$data5( 0, 3 ),",",&$data5( 0, 5 ),"\n";
print $data5->( 1, 0 ),",",$data5->( 1, 3 ),",",$data5->( 1, 5 ),"\n";

exit;    #おしまい

#サブルーチン
sub test{
#@_=>引数がデフォルトで格納されている
#つまり、@_=@logと自動的にしてくれている
    local( @tmp );
    foreach ( @_ ){
        chomp;
        push( @tmp, [ split( /,/ ) ] );
    }
    return @tmp;
}#test END

sub test2{
    ( split( /,/, $log[ $_[0] ] ) )[ $_[1] ];
}


>$ans=$data[0][3];
という意味では、その3がとっつきやすいかもしれませんね。


☆と、いろいろ考えている間に、R.Mさんの書き込みが(^^;)


謎の人R [WriteDate : Mon Apr 23 05:22:56 2001]

ちなみに@logはグローバルなものになっているので、
sub test2{
   ( split( /,/, $log[ $_[0] ] ) )[ $_[1] ];
}
と、いきなり$log[]を使っています。


ひよこ [MAIL] [URL] [WriteDate : Mon Apr 23 06:08:19 2001]

謎の人Rさん、ありがとうございます。

たくさんのサンプル助かります。m(_._)m
ちょっとまだわからないことばかりで、コメントつけれませんけど
参考にしながら勉強させて貰います。
perlは比較的取っつきやすい言語だと言われますがその分、不可解な
所も(たぶん私が理解してないだけ)たくさんあって奥が深いです。

また、躓いたらお世話になるかも(^^;
その時はまた宜しくです。今回のご回答に感謝します。

とりあえず完了ってことで・・・(勉強はまだまだ続きますが)


ひよこ [MAIL] [WriteDate : Mon Apr 23 06:15:27 2001]

> ちなみに
>> sub newArray{local(@a)=split(/,/,$_[0]); return \@a;}
> これは「無名」ではありません
あちゃ〜 勘違いしてました(汗)
RMさん、すみません。飛ばして見てたm(_._)m

こちらも参考にさせていただきます。ありがとうございました。
#まだ道のりは遠い・・

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]
ChaichanPAPA's World