• ベストアンサー

perlのリファレンス

Perlのクラスとそのインスタンスについて疑問があります。 newでインスタンスを生成して、それを代入した場合には オブジェクトはコピーされるのでしょうか? $a = new MyClass; $b = $a; # aをコピーしてbを作る? この状態の時にaとbが同じインスタンスを指しているのか、 コピーされた別のインスタンスを指しているのかわかりません。 コピーされるとして、逆にコピーしない方法はありますか? PHPでいうと以下の書式のことがしたいのです。 $b =& $a; リファレンスを使えばできそうですが、なんだか2回コピーしている ような気がします。 $ref_b = \$a; $b = $$reb_b; PHPでいう is_a のような関数が見つけられなかったので、 どうやって上記のことを確認すればよいのかわかりません。 Perlの代入はすべてコピーと考えてよいでしょうか? アドバイスなどいただけると幸いです。

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

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

new して返ってくるのはインスタンスのリファレンスなので、Cで言うところのポインタの持ち回りと一緒です。 やっつけで↓のようなスクリプトを書いてみました。 package Foo; sub new { my $self; $self = {}; $self->{value} = shift; bless $self; return $self; } package main; my $foo = Foo::new("hello, world"); print $foo, "\n"; my $bar = $foo; print $bar, "\n"; my $baz = Foo::new("Howdy!"); print $baz, "\n"; $baz = $foo; print $baz, $baz->{value}, "\n"; $baz->{value} = "hogehoge"; print $foo->{value}, "\n"; 実行例です。 Foo=HASH(0x1635db8) Foo=HASH(0x1635db8) Foo=HASH(0x1635fc8) Foo=HASH(0x1635db8)hello, world hogehoge 見ての通り、リファレンスを代入しても中身がコピーされることはありません。 逆に別の変数を経由して中身を書き換えると、元のものにも影響します。

angband
質問者

お礼

お礼が遅れてすいません。 どうもありがとうございました。

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

その他の回答 (3)

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.4

オブジェクトはコピーされません。 オブジェクトのコピーは、Storableモジュールが便利です。

angband
質問者

お礼

お礼が遅れてすいません。 どうもありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

おまけ: 普通 new が返すのはリファレンスですが, どうにも気になるときには attributes モジュールの reftype って関数が使えるかも. my $a = new MyClass; eval { attributes::reftype($a); }; # $@ eq '' なら $a はリファレンス

angband
質問者

お礼

お礼が遅れてすいません。 どうもありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

new してるってことは new の中で bless してると思うので, リファレンスが返ってきているんじゃないでしょうか. で, このリファレンスを代入しますから, 「同じインスタンス」を指すと思います.

angband
質問者

お礼

お礼が遅れてすいません。 どうもありがとうございました。

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

関連するQ&A

  • perlで関数のプロトタイプでリファレンスの場合は?

    perlで関数にプロトタイプを記述しようとしたのですが、リファレンスの場合はどうしたらよいのでしょうか? sub test(\$[ここに必ずリファレンス型]){ my($sca, $ref) = @_; } my $a = "A"; my @b = ("1", 2, "3"); test($a, \@b);

    • ベストアンサー
    • Perl
  • PHP5 オブジェクトのリファレンスとデストラクタ

    PHP5.0.4を使っています。 原因不明の現象に悩まされていましたが、再現する最小限のコードがわかりました。 class Foo { function __destruct() { } } $bar=&new Foo(); $bar=&new Foo(); というコードで、最初の$barへの代入ではちゃんとFooクラスのオブジェクトへのリファレンスが代入されますが、2回目の代入では結果として$barはNULLになってしまいます。 (1)リファレンスでなく値の代入にする (2)変数名を変える (3)2回目の代入の前に$barをunset()する (4)デストラクタの宣言を削除する のいずれかで2回目もFooオブジェクトが$barに代入されるのですが、(1)は実際はそこそこ大きいオブジェクトなのでコピーするのは無駄、(2)実際はループになっており2回目以降の変数名を変えるのは不可能 ということで、現在は(3)の対処をしています。 Q1.何故こういう現象が起こるのか Q2.デストラクタ宣言の有無で変わるのは何故か Q3.どういう対処が正しいのか 実際の処理は、こんな感じです。 foreach($aaa as $x) {  $bar=&new Foo($x);  if( $bar->test() ) $value[]=&$bar;  /*ここに else unset($bar); を入れるとOK */ }

    • ベストアンサー
    • PHP
  • printの表示形式について質問です。

    現在PHPを著書を利用して独学で習得中です。 余り詳しい説明のない著書のようで、 今一要領がつかめないのですが、 下記のようなプログラミングを行いました。 --<program_start>-- <?php class MyClass{ function __construct(){ print("オブジェクトが生成されました<br/>"); } function __destruct(){ print("オブジェクトが破棄されました<br/>"); } function calculate($a, $b){ print("$a + $b は ".$a+$b." です<br/>"); } } $objCls = new MyClass(); $objCls->calculate(2, 3); ?> --<program_end>-- その結果下記のように表示されました。 --<answer_start>-- オブジェクトが生成されました 5 です オブジェクトが破棄されました --<answer_end>-- 著書では結果の部分の計算表示が 2 + 3 は 5 です となっていますが同じように表示されません。 どこか誤っているのでしょうか?

    • ベストアンサー
    • PHP
  • PARL言語のリファレンスの解釈は?

    最近 学習し始めたばかりの Perl ですが、 リファレンスとは、機械語に出てくるメモリ(記憶装置)の アドレス(番地)という解釈でよいのでしょうか? (画面上16進数の番地等は表に出てこないようですが・・) また、下記サンプルの場合 リファレンスを番地と仮定しまして、 配列@arrayの番地は、5個ぶんのメモリ領域が確保されるのでしょうか? そしてスカラー$ref_arrayに代入される番地は、 その5個ぶんの番地の先頭番地でしょうか? (スカラー変数1つに、5個のデータは入らないですよね?) @array = (1,2,3,4,5); $ref_array = \@array; 表現的にわかりにくいかもしれませんが よろしくお願いします。

    • ベストアンサー
    • Perl
  • オブジェクトの参照を返す関数の扱い

    オブジェクトの作成と関数との関係を勉強していますが参照の使い方に関して質問させていただきたいと思います。 以下のような簡単なプログラムを作りました。 myclass.cpp myclass.h で記述されたクラスmyclassは整数を一つ持ち、show_value関数でその整数を表示し、say_heyで"hey"という文字を出力するというものです。 このクラスを利用するプログラムとしてmain.cppをつくりました。このなかには2つの関数が使われます。 -オブジェクトをつくりそれをオブジェクトとして返す関数(return_obj)   -オブジェクトをつくりそれの参照を返す関数(return_ref_obj) これらの関数を用いてオブジェクトをつくり、そのオブジェクトを戻り値としてmainのなかでオブジェクトのshow_value関数で保持する整数を表示する、というものです。 myclass.h-------------------------------- class Myclass{ public: int my_int; Myclass(); ~Myclass(); void show_value(); void say_hey(); }; myclass.cpp---------------------------------- #include "myclass.h" #include <iostream> using namespace std; Myclass::Myclass(){}; Myclass::~Myclass(){}; void Myclass::show_value(){ printf("%d\n", my_int); } void Myclass::say_hey(){ printf("hey\n"); } main.cpp------------ #include <iostream> #include "myclass.h" using namespace std; //オブジェクトをつくりそれをオブジェクトとして返す関数(return_obj)   Myclass return_obj(int int_in){ Myclass myobject; myobject.my_int = int_in; //引数をオブジェクトのmy_intに渡す return myobject; } //オブジェクトをつくりそれの参照を返す関数(return_ref_obj) Myclass& return_ref_obj(int int_in2){ Myclass myobject; myobject.my_int = int_in2;   //引数をオブジェクトのmy_intに渡す Myclass& ref_of_myclass = myobject; return ref_of_myclass; } void main(){ Myclass returned_obj = return_obj(1); //関数に1を渡し、1を保持するオブジェクトを作成 returned_obj.show_value(); //整数(1)表示 returned_obj.say_hey(); Myclass& ref_obj = return_ref_obj(2); //関数に2を渡し、2を保持するオブジェクトを作成し参照として受け取る ref_obj.show_value(); //整数(2)表示 ref_obj.say_hey(); } プログラムを実行した出力------------------- 1 hey -858993460 hey このようにオブジェクト自体を返してコピーしたもの(return_obj使用)はshow_valueでただしくオブジェクトに保持された数が表示されますが 参照でオブジェクトを返したもの(return_ref_obj使用)はアドレスのような数列が表示されます。 質問A これはオブジェクトの参照を返す関数(return_ref_obj)でオブジェクトを作成しても、そのオブジェクトが関数の中でのみ実在しており、関数がおわるとその実体がなくなるためではないかと解釈しているのですがそれで正しいでしょうか? 質問B 関数でオブジェクトを作成してそれをプログラム本体に渡すときはreturn_objのようにオブジェクト自体をコピーしなければ参照などで渡すことはできないのでしょうか? クラスと参照自体勉強を始めたばかりで色々と初歩的な間違いもあるとは思いますが、よろしくお願いします

  • LinuxリファレンスとUNIXリファレンスの違いは?

    LinuxリファレンスとUNIXリファレンスの違いは? 当方CentOSやCygwinを使用していますが、リファレンスが必要になったので購入しようと思いましたが、LinuxリファレンスとUNIXリファレンスの2種類があって、どちらを購入すれば良いのか全く分かりません。中身もほとんど似ているようです…。 Pocket Referenceシリーズでは ・『Linuxコマンド ポケットリファレンス』 ・『UNIXコマンドポケットリファレンス ビギナー編』 があって、 ソフトバンク クリエイティブ社からは ・『Linuxコマンドブック ビギナーズ 第2版 コマンドブックシリーズ』 ・『UNIXコマンドブック 第2版』 があるのですが、UNIXリファレンスとLinuxリファレンスの違いは何でしょうか。 ------------------------------------------------------- 『Linuxコマンド ポケットリファレンス』http://www.amazon.co.jp/%E3%80%90%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88%E3%80%91-Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89-%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9-Pocket-Reference/dp/4774138169/ref=pd_ts_b_21?ie=UTF8&s=books 『UNIXコマンドポケットリファレンス ビギナー編』http://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-UNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9-%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E7%B7%A8-POCKET-REFERENCE/dp/4774133493/ref=sr_1_5?ie=UTF8&s=books&qid=1262233838&sr=1-5 『UNIXコマンドブック 第2版』http://www.amazon.co.jp/UNIX%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E7%AC%AC2%E7%89%88-%E5%B0%8F%E9%87%8E-%E6%96%89%E5%A4%A7/dp/479733259X/ref=pd_sim_b_4 『Linuxコマンドブック ビギナーズ 第2版 コマンドブックシリーズ』http://www.amazon.co.jp/Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF-%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E3%82%BA-%E7%AC%AC2%E7%89%88-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%96%E3%83%83%E3%82%AF%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E7%94%B0%E8%B0%B7/dp/4797340053/ref=sr_1_3?ie=UTF8&s=books&qid=1262234273&sr=1-3

  • Ruby 特異メソッドのnewが先に実行?

    Rubyのインスタンス生成について質問があります。 通常クラスを定義する場合は class Hoge ; def hello(); pirnt "hello"; end であると思います。 ただ Hoge = Class.new(); でもクラスは定義できるとききました。 ただこの場合Hogeクラスに定義できるのは HogeというClassクラスから作られた特異クラスとしてのHogeに 特異メソッドのみを定義できるということですよね? 通常のインスタンスメソッドは定義できませんよね? ではでは、 hoge = Class.new(); とした場合はどうなるのでしょうか? この場合は Classクラスの純粋なインスタンスとなるのでしょうか? 前者の定義とおなじ仕方ですが代入先が、通常の変数です。 この場合は、クラスオブジェクトとして生成されるのですか? オンラインマニュアルをみたところ 「新しく名前の付いていない superclass のサブクラスを生成します。 superclass が省略された時にはObject のサブクラスを生成します。 名前のないクラスは、最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。」 とあります。 上記内容は Classクラスの特異クラスとして定義されている特異メソッド(new)です。 これは Class.new()で作られたインスタンスを代入する先が定数であればその定数名と同じクラスを定義しつつそのClassクラスのクラスオブジェクトを生成するという意味合いでまちがいないでしょうか? 上記のとおりであれば hoge =Class.new()の場合は、やはりhogeというクラスを定義することになるのでしょうか? クラス定義は定数でなければならないはずですよね。 ただ実際、 p hoge;として出力すると#とひょうじされています。これはhogeがクラスオブジェクトではなく ただのインスタンスであるということでしょうか? であるならばこの hoge = Class.new()の式のnewはClassクラスオブジェクトに定義された特異メソッドではなく Classクラスに定義されたnewメソッド・・・・・つまりClassクラスに定義されたインスタンスメソッドの方のnewメソッドだとおもうのですが・・・・・・。 つまりこちらのメソッドですね。 「new( ... ) クラスのインスタンスを生成して返します。このメソッドの引数はブロック引数も含め initialize に渡されます。」 ※オンラインリファレンスから参照しました。 しかし 通常メソッドの検索は特異メソッドからはじまりその後クラスのインスタンスメソッド->親クラスのメソッドと 検索して行くとあります。 必ず先に、特異メソッドを実行しているはずだと思うのですが・・・。 やはり特異メソッドnewを実行しているのでしょうか? 長々すみませんが、ご教授ください。

    • ベストアンサー
    • Ruby
  • ハッシュリファレンスの未定義

    サブルーチン/ハッシュリ/ファレンスで悩んでいます。 my (@r); $r[1]{"A"} = "1-A"; # 代入 &s(\@r); print $r[1]{"A"},"\n"; # 参照 print $r[2]{"B"},"\n"; # 参照 サブルーチン側でできない。 # sub s() { my ($c)=@_; @$c[1]->{"A"} = "1111-AAAA"; # もちろん代入できる @$c[2]->{"B"} = "2-B"; # 代入 これができない(ハッシュリファレンスの未定義エラー) } サブルーチン側で新規ハッシュのところに代入ができないのですが どのようにすればいいのでしょうか。

    • ベストアンサー
    • Perl
  • コピーコンストラクタが呼び出されていない?

    コピーコンストラクタが呼び出されていない? class myclass { public: int x; myclass(const int& init_); //コンストラクタ myclass(const myclass& init_); //コピーコンストラクタ const myclass operator+(const myclass& rhs); //加算 const myclass& operator=(const myclass& rhs); //代入 }; と定義したクラスを使ってオブジェクトを生成するときに妙な挙動をしています。 myclass mc1(10); myclass mc2 = 20; myclass mc3(mc1 + mc2); //コピーコンストラクタが呼ばれるはず このコードを実行した結果は、mc3(mc1+mc2)では自分で定義したコピーコンストラクタは実行されませんでした。 mc3(mc1 = mc2)と実行すれば、コピーコンストラクタが実行されたのですが、この違いはどこにあるのでしょうか。 そもそも、myclassとmyclass&は全く別のものなのでしょうか?

  • 参照渡しやリファレンスを返す事について

    今疑問に思っているのが、「&」を付ける全ての事象についてす。 今まで参照渡しの方が効率や都合が良い場合にしか利用していませんで したが、「特に値渡しで構わない場合も、参照渡しにした方が良いの か?」という事から出てきた疑問です。 引数の値を直接操作する事はあまり良くない、と言われるのはこの辺の 絡みだと思うのですが、仮に関数内で引数の値を再セットする事を 忠実に守っていた場合、値渡しより常に参照渡しである方がメモリ 効率は良いと思います。(結局関数内で値渡しをする為、消費量としては 大きいと思いますが) 個人的には必要のある時にしか参照渡しを行わないという考えを変えるつもりは ありませんが(それが妥当な目的と利用法であると思うので)、 プロな方としてはどうなのかな、という事を思ってしまったのです。 次に、仮に変数同士で行った場合、ポインタもどきの動作をしている 事から、意味合いは通じるのですが、インスタンスを生成する場合や そのメソッドを呼び出して戻り値がオブジェクトの場合に見受けられます。 (マニュアルを見るとPHP5の場合、インスタンス生成時にそれを利用する 事は非推奨のようですが) 疑問なのは、インスタンスを初めて生成してオブジェクトが作られているのに 「&」で何を参照しに行っているのか?(クラスという雛形?) メソッドが終了したら内部の変数は開放されると思うが、それを参照 する事が何故可能なのか? リファレンス元をunset()してもリファレンス先が消えない事と同じ意味か? そういうものだと言ってしまえばそれでおしまいですが、 そういう疑問があるせいか、それの使いどころが分かりません。 加えてメソッドに関しては、呼び出し時に「&」をつけていたり メソッドの定義自体に「&」があったりして、使い方が分かりません。 呼び出し時の「&」は戻り値の参照でしょうけど、メソッド定義自体の 「&」が意味不明です。 ここばっかりはマニュアルを見ても理解出来ませんでした。 定義の参照って?という感じで考えが止まってしまいます。 (呼び出し時は、require等がされた時点でメモリで格納されている対象を見ている、という事なのか?) どなたかご教示願います。 今、かなりPHPについて悩んできてしまいました(笑)

    • ベストアンサー
    • PHP
このQ&Aのポイント
  • TD-4420DNの印字にかすれや縦線がある問題について相談です。
  • クリーニングしても改善しないため、サーマルヘッドの交換を検討していますが、他の要因もあるのか知りたいです。
  • ブラザー製品に関する問題で、印字のかすれや縦線が醜い状態になっており、修理やパーツの交換が必要か相談したいです。
回答を見る

専門家に質問してみよう