[Perl]配列データを直接編集するための方法

このQ&Aのポイント
  • Perlを使って配列データを直接編集する方法について教えてください。
  • 特定のメソッド内で、受け取った配列データを編集する方法を教えてください。
  • 配列の要素を別のメソッドで変更することは可能でしょうか?方法を教えてください。
回答を見る
  • ベストアンサー

[perl]メソッドの引数で受け取った配列データを直接編集したい

現在、業務でperlプログラムを書いてます。 perlを初めて2か月、プログラムは ほぼ初です。 よろしくおねがいします。 例えば以下のようなコードで、「sub_func」というメソッド内で「main」メソッド内の配列データを直接編集したいのですが、うまくいきません。 これは、引数で渡しているのは配列の「ポインタ」ではなく「リファレンス」であるため、「sub_func」というメソッド内で、新たに「array_ref」という配列の実態を作成してしまっているのだと認識しています。 そのため、「main」メソッドに戻ったタイミングではデータは元に戻ってしまうのだと思っています。 sub sub_func {    my ($self, $array_ref) = @_ ;    $array_ref = [4,5,6];   # returnはせずに、引数で指定したデータに格納したい } sub main {    my ($self) = @_ ;    # メソッドに渡すデータ    my $data = {       array => [1,2,3],    };    my $data2 = [1,2,3];    my @data3 = (1,2,3);    # メソッドの中で、$data->{array}を [4,5,6] に変えたいが・・・    $self->sub_func( $data->{array} );    $self->sub_func( $data2 );    $self->sub_func( \@data3 );    # この時点で、どれも [1,2,3] のまま } 私の認識は間違っているのでしょうか?? また、どのようにすれば配列の要素を別のメソッド内で編集できるのでしょうか?? 御助言をお願いします。

  • Perl
  • 回答数1
  • ありがとう数2

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

(ぼそ) 「ポインタ」と「リファレンス」は同じものだと思っていい (endぼそ) 現状では サブルーチン sub_func で引数をいったん変数 $self, $array_ref にコピーし, この「コピーした」$array_ref を書き変える という動作です. コピーした時点で $_[0] と $self, $_[1] と $array_ref は「同じ値を持つ別の変数」です. だから, サブルーチン main の変数はどれも変化しません. ちなみに $_[1] = [4, 5, 6]; だと @data3 以外は書き変わります. まあ, これも妥当かな. ということで @$array_ref = (4, 5, 6); では?

mikane10
質問者

お礼

Tacosanさん、ご回答ありがとうございます。 「ポインタ」と「リファレンス」は多少違うものと認識していたので、こういったところで違ってくるのかと思ってました・・・。 $self, $_[1] と $array_ref は「同じ値を持つ別の変数」というのは認識していたのですが、なぜ引数で渡したアドレスをそのまま参照してくれないのか不思議でなりませんでした。 ご指摘の件、試してみたところ、正常に動作するようになりました。 ありがとうございました。

関連するQ&A

  • perlのクラスについて

    perlでクラスを作成しています。その際、コンストラクタnewで無名配列を定義して、funcメソッドで、この無名配列に値をいれるにはどうすればよいでしょうか? sub new { my $class = shift; my $self->array = []; bless($self, $class); return $self; } sub func { my $self = shift; $self->arrayに配列のデータを入れる。 }

    • ベストアンサー
    • Perl
  • perlでサブルーチンへの複数の配列渡し

    perlでサブルーチンに配列を渡しているのですが、 引数としている配列が1個の場合は問題ないのですが、 複数渡すと、第2引数以降が渡りません。 どの様にすれば上手くできますか。 例1 #!/usr/bin/perl @x1 = (14, 11, 5, 12, 8, 15); @x2 = (12, 10, 8, 9); print "main : @x1 \n"; &test(@x1); sub test { my (@arg1) = @_; print "sub : @arg1 \n"; } 結果 main : 14 11 5 12 8 15 sub : 14 11 5 12 8 15 例2 #!/usr/bin/perl @x1 = (14, 11, 5, 12, 8, 15); @x2 = (12, 10, 8, 9); print "main : @x1 \n"; print "main : @x2 \n"; &test(@x1, @x2); sub test { my (@arg1, @arg2) = @_; print "sub : @arg1 \n"; print "sub : @arg2 \n"; } 結果 main : 14 11 5 12 8 15 main : 12 10 8 9 sub : 14 11 5 12 8 15 12 10 8 9 sub : 引数1に全てが設定されて、引数2に設定されていない。

    • ベストアンサー
    • Perl
  • スカラと配列の参照を引数で渡したい。

    sub test{ my ($ref) = @_; print ref $ref; } my @a = (1, 2, "A"); #test(\"aaaa"); # SCALER #test(\['a', 1]); # REF #test(\@a); # REF # ARRAY test( \(1, 2) ); # スカラー? 引数を参照で渡すとメモリ効率?が良いと思い、スカラの場合は \"スカラー"で渡せましたが、 配列の場合は、直接 \('配列', 'です') は無理なのでしょうか? また、基本的に参照で渡すより、普通の型で渡した方がソースは読みやすいでしょうか?

    • ベストアンサー
    • Perl
  • なぜmainメソッドにだけ固定の引数があるのか?

    Javaの初心者です。 勉強していてふと思ったのですが、なぜmainメソッドだけに main(String[] X) のようにのストリング型の配列を引数に必ず設定しないといけないのでしょうか? 他のメソッドであれば、引数の有る無しをプログラマが決めることができますよね? そのため疑問に思ったのですが、どなたか教えていただけないでしょうか?

  • perlの引数が不安定になります。

    perlの引数が不安定になります。 具体的には、 同じ値が返されるはずなのに、返されません。 私の持っている、入門用の本を調べたのですが全くわかりません・・・ 分かる方、教えていただけないでしょうか。 宜しくお願い致します。 open IN, 'Testfile.txt'; #Testfile.txtは、ある程度の大きさがあったほうが良いと思うので、ヤフーのトップページのソース全てなどが適当かもしれません。 my @array = <IN>; close IN; my $count = "1"; print &test(@array,$count); #何も表示されない print "<HR>"; print &test2($count,@array); #1が表示される。 sub test() { my (@array,$count) = @_; return $count; } sub test2() { my ($count,@array) = @_; return $count; }

    • ベストアンサー
    • Perl
  • 引数(配列)について

    呼ぶ側: Sub main()  Call func(test(),test_id) end Sub 呼ばれる側:  Private Sub func(Byref test() as string, Byval test_id as long) と言う関係がある場合で 引数(1)test() の値がなく渡したくない場合は、どのように記述すればいいのでしょうか? 引数(2)test_id の値がなく渡したくない場合は、0を渡しています  また、呼ぶ側で test() を宣言し、tast()=""を代入すれば問題ないことは分かっているのですが、test()の変数宣言せずに何とかなりませんでしょうか? 宜しくお願いいたします

  • 引数を受け取る@_について

    subプロシージャ(関数)の引数について教えていただきたいのですが,例えば, @data1=(1,2,3,4,5); @data2=(6,7,8,9,10); &stat::cov(@data1,@data2); などとすると,sub cov{}で@_という配列の中に一緒に格納されますよね。しかし私としては@data1に格納されているデータと@data2に格納されているデータを別の配列に渡したい(別の配列で受け取るようにしたい)のです。 考えた策としては sub cov{ my $n=@_; my $h=$n/2; for($i=0;$i<$h;$i++){ $x[$i]=shift(@_); } for($k=0;$k<$h;$k++){ $y[$k]=shift(@_); } (以下省略) のように,shift関数で1つずつずらして違う配列に格納していくという方法なのですが,これは@data1と@data2に格納されているデータ数が等しい場合で無いと使いものになりません。 指定した引数を@_以外の配列で受け取らせる方法などはないものでしょうか?ちなみにPerlはまだ初心者にも達していないド素人ですのであまりプロ志向のものは勘弁してください(それでもなければ仕方ありませんが、、、)。

    • ベストアンサー
    • Perl
  • Perlのデータ構造について

    Perlのデータ構造でわからないところがあります。 ハッシュの配列で、以下の構造がある場合 my %hash_array = ( 1=>["aaa", "bbb"], 2=>["ccc", "ddd", "eee"], 3=>[], 4=>["fff"] ); print $hash_array{1}[0]; # aaaが表示される。 print $hash_array{2}[2]; # eeeが表示される。 ですが、 $hash_array{1}は 2 $hash_array{2}は 3 $hash_array{3}は 0 $hash_array{4}は 1 のように個数を表示させるのは、どうすればよいでしょうか? Perlのデータ構造に詳しいサイトや書籍はありますか? また、Perl 5.6.1から Perl 5.8.7に乗りかえようとしていますが、 データ構造など大幅に変わった点はあるのでしょうか?

    • ベストアンサー
    • Perl
  • Perlのサブルーチンの引数引継ぎ?

    こんにちは。 Perlの引数について質問です。 サブルーチンに引数を渡し、サブルーチンの中で他のサブルーチンをよんでいます。 すると引数を渡していないサブルーチンにまで引数が与えられてしまっているようです。 @_で受け取ると引数が渡されてしまい、$_[0]だと渡されずにすみます。 これはなぜなのでしょうか?Perlには引数を引き継ぐルールでもあるのでしょうか? 以下、サンプルです。 -------------------------------- &test('引数です'); sub test { &test2; } sub test2 { (my $hoge) = @_; } -------------------------------- $hogeに「引数です」が入ります。 &test2;を&test2();とすると大丈夫です。

    • ベストアンサー
    • Perl
  • メソッドの引数に配列を使う

    public class TurtleFigures { /** 複数の図形を書く */ public static void drawFigures(・・・・) { while (true) {     // 無限ループ ・・・・ // 引数の配列を順番に操作し、     // step() メソッドを利用して図を書く } } } public static void main(String args[]) { // 4個のリモコンの配列を作る TurtleRemoCon remocons[]; remocons = new TurtleRemoCon[4]; // 各リモコン オブジェクトを作成 // 初期座標(100, 200), 速度 dx=10, dy=5 remocons[0] = new TurtleTrap(100, 200, 10, 5); // 初期座標(150, 250), 速度 dx=-10, dy=3, オレンジ色 remocons[1] = new TurtleTrap(150, 250, -10, 3); remocons[1].setColor(java.awt.Color.ORANGE); // 初期座標(50, 250), 速度 10, 長さ 20, 緑色 remocons[2] = new TurtleCircler(50, 250, 10, 20); remocons[2].setColor(java.awt.Color.GREEN); // 初期座標(50, 250), 速度 10, 幅 150, 高さ 100, 赤色 remocons[3] = new TurtleRectangle(50, 250, 10, 150, 100); remocons[3].setColor(java.awt.Color.RED); // 複数のリモコンを操作して図を書く drawFigures(remocons); } } 上のプログラムでmain内のdrawFigures(remocons);から public static void drawFigures(・・・・)の・・・にremocons を受け取るための記述方法が分からず困っています。 誰か教えていただけませんか?

    • ベストアンサー
    • Java

専門家に質問してみよう