Rubyの戻り値とオブジェクトの寿命について

このQ&Aのポイント
  • Rubyでは関数内で宣言したオブジェクトの参照は保障されるため、関数を抜けてもアドレスの内容が破棄されない
  • メソッド内で宣言したオブジェクトの寿命は、そのオブジェクトが参照される範囲で継続する
  • Rubyのオブジェクトの参照にはポインタの概念があり、戻り値として返したオブジェクトの参照も保持される
回答を見る
  • ベストアンサー

戻り値で返したオブジェクトの寿命について

Ruby初心者です。 【前置き】 メソッドで宣言した変数(以下arr)に値(以下[1,2,3])を代入し戻り値として返した場合、 メソッドの戻り値(以下retArr)には、[1,2,3]への参照(arr.object_id)が設定されると認識しております。 ----------------------- def method arr = [1,2,3] return arr end retArr = method() ----------------------- 【質問】 C言語の場合、関数内で宣言したローカル変数のアドレスを戻り値として返却した場合、 関数を抜けた時点で、そのアドレスの内容は保障されなくなりますが、 1.Rubyではその様な問題がなく動作するのは、何故でしょうか? 2.また、メソッド内で宣言したオブジェクト(上記[1,2,3])の寿命はいつまでなのでしょうか? 【備考】 いろいろと調べてみたのですが、オブジェクトの参照(object_id)は、ポインタに近い概念であることは記載されているのですが、その仕組みを理解できずに悩んでします。

  • Ruby
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4845/10255)
回答No.1

>1.Rubyではその様な問題がなく動作するのは、何故でしょうか? Rubyだと、戻り値は、ローカル変数のアドレスでは無いからです。 Cだと、mallocしたエリアのアドレスに相当します。 >2.また、メソッド内で宣言したオブジェクト(上記[1,2,3])の寿命はいつまでなのでしょうか? オブジェクトの寿命は、変数のスコープとは無関係です。そのオブジェクトのへの参照が0個になると寿命が尽きます。メモリエリアが回収されるのは寿命が尽きた後のガベージコレクションの時です。 a=[1,2,3] #=> 参照が1個 b=a #=> 参照が2個 a=3 #=> 参照が1個 b="A" #=> 参照が0個 →この段階でオブジェクト[1,2,3]の寿命が尽きる 「寿命」という言葉の定義によっては、参照が0個になった後のガベージコレクションの時点という人もいるかもしれません。

kudou_misaki
質問者

お礼

ご回答ありがとうございます。 すごく分かりやすい説明で、スッキリしました。

関連するQ&A

  • 戻り値がクラスオブジェクト

    VB初心者でわからないので教えてください。 ある関数を呼び出して戻り値を取得するのですが、その戻り値がクラスオブジェクトとなっています。いろいろ調べてみましたが、いい結果にヒットしなかったので今回質問してみました。 言語はVB6.0です Function 関数A(A as String, B as String) dim C as Class1 set C = new Class1 Class1で宣言された変数に値を入れる処理     関数A = C end Function イメージはこんな感じです。 すみませんが解決策を教えてください。。。。

  • visioでシェイプオブジェクトのIDを取りたい

    ステンシルのシェイプテンプレートをマクロで張り付けているところなのですが、 その張ったオブジェクトを操作したいです。 /**************/ ◆困っていること DROP関数を実行した際に、 新しくオブジェクトIDが振られるわけですが、そのIDが取れず困っています。 ◆試したこと(1) IDを取れなかったので DROP関数の戻り値がシェイプオブジェクト だったようなので、 シェイプオブジェクト = DROP関数(※略) として見たのですが オブジェクト変数または With ブロック変数が設定されていません となり、 戻り値なしでDROP関数を使って張り付けています。。 ◆試したこと(2) PAGEオブジェクトから、 現在の最大のインデックスを取れるか試してみたのですが (MSDNのページを見てそれっぽい関数は色々試してみたのですが出来ませんでした。。) どちらの方法も出来そうな気はするのですが。。 .

  • C言語 関数の戻り値と自動変数

    かなり基礎的な質問になるのですが、疑問に思うことがあり、質問をさせていただきます。 関数内で宣言した変数を戻り値として使う場合ですが、ポインタなどではなく実体の場合でも、静的変数として宣言をしたほうが良いのでしょうか? 現実的に考えると、プログラムが関数から出て、呼び出した側の関数が戻り値を受け取るまでの瞬間に、その領域が書き換えられる可能性は極めて低いと思うのですけど、C言語の仕様としてはどうなのでしょうか? 関数内で宣言した戻り値に使う変数には、必ずstaticをつけた方が良いのでしょうか? もしおわかりでしたら教えて下さい。

  • インスタンスとオブジェクト

    こんばんは。 変数について教えて下さい。 プログラム自体が初めてなので 「たのしい Ruby 第3版」を読んでいます。 ずっとインスタンスとオブジェクトの違いが曖昧なままです。 その本の「クラスとモジュール」という章にて クラスを定義する構文。 インスタンス変数とローカル変数の違いですが、 以下の説明で一部理解できずにつまずいています。 ―――――――――――― @ で始まる変数は インスタンス変数 といいます。 ローカル変数はメソッドごとに異なる変数として扱われますが、 インスタンス変数は同じインスタンス内であれば、 メソッド定義を超えてその値を参照したり、変更したりできます。 なお、初期化されていないインスタンス変数を参照すると nil が得られます。 インスタンス変数は、インスタンスごとに違う値を持つことができます。 またインスタンス変数は、 インスタンスがある間は値を保持しておいて 何度でも利用することができます。 一方、ローカル変数はメソッド呼び出しごとに新しく割り当てられるため、 メソッドから抜けると値を忘れてしまいます。 ―――――――――――― ここで分からないのは、 ・ローカル変数が "メソッドごと" に異なる変数として扱われる ・インスタンス変数は同じ "インスタンス内" であれば、 メソッド定義を超えてその値を参照したり、変更したりできます の部分です。 Webで検索してますが、 プログラミング経験ありを前提で書かれているような。 他の言語も知らないので分からない、そんなページが多いです。 人に聞くからには 自分でも頑張って理解できるように考えますので、 どうか回答よろしくお願いします。

    • ベストアンサー
    • Ruby
  • メソッド宣言の戻り値の型にクラス名を使うには?

    メソッドの戻り値の型にクラス名を使ってるプログラムを見かけたのですが、例えばクラス名を public class Player{ とします。そして Playerクラスのメソッド宣言に  private   Player(戻り値の型) startRun(メソッド名) { とあります。 これは戻り値の型にクラス型の変数を使ってユーザー定義してると思うのですが使い方が分かりません。 javaのサイトはできるだけ調べたのですが戻り値の型にクラス名を使うにはどうすればいいか分かりませんでした。 この使い方を教えてくれるサイトを教えてください。 基本型と参照型のStringクラスについて教えてくれるサイトはたくさん見かけたのですが…。 お願いします。

    • ベストアンサー
    • Java
  • 関数内で数値入力したときの戻り値は?

     数値を入力して変数に格納する、という作業を複数回繰り返すような数値入力のための関数をつくったとします。そのような場合、関数の宣言や戻り値はどのようにすればよいのでしょうか?  グローバル変数を用いたときにはうまくいったのですが、ローカル変数にかえようとしたらmain関数の中で値が割り当てられていません、となってしまいました。  教えてください。お願いします。

  • オブジェクトの消滅と関数の戻り値オブジェクト

    public sub test1() { dim hoge as classX = tes2() test2.getHogehoge() } public Function test2() as classX { dim ret As New classX("初期化") return ret } 大変簡略化してますが上記2つの関数があった場合 関数test1でclassX型のアドレスhogeに、test2()が返す classX型オブジェクトの参照を代入しています。 でこの実体というかインスタンスretはtest2()の中の スコープで消滅する自動変数として生成されています。 んで実際関数test2を抜けるときretのインスタンスは 破棄されるのにtest1ではそれをhogeアドレスに代入して 使用していいのでしょうか?

  • クラスから自分のオブジェクトを操作するには

    高橋麻奈著の「やさしいJava」を買って、Javaプログラミングをはじめたのですが、どうしても分からないことがあるので質問させてください。 次のようなコードがあります。 class Abc{  public static void main(String arg[]){   Def de = new Def();   de.object_null();   Def de2 = new Def();   de2.object_null();   Ghi gh = new Ghi();   gh.object_null();  } } class Def{  int d,e,f;  Abc abc;  Def(Abc a,int i1,int i2){   //略  }  public void object_null(Abc a){   abc = a;   abc.de = null;  } } class Ghi extends Def{  Ghi(Abc a,int i1,int i2){   super(a,i1,i2);  } } Defクラス側から自分自身のクラス変数deをnullにする場合、public void object_null()メソッドのような方法でクラス変数を指定してnullにしていました。 しかし、この場合、クラス変数de2のobject_null()メソッドではde2をnullできないし、 サブクラスGhiから、クラス変数ghをnullにする場合も、クラス変数deを指定してしまいます。 クラス側から自分自身のクラス変数を指定する良い方法を教えてください。 よろしくお願いします。 #ここは半角スペース無効なんですね(^^;

    • ベストアンサー
    • Java
  • const int&の戻り値について

    const int&の戻り値について c++で「const int&(const int a)const{...」についてのメンバ関数がありますが、そのconst int&はどういう意図に使われるのでしょうか。 &があるので、アドレスを返すと思いますので、ポインタ変数に入れるだけでしょうか。それでもポインタ変数とメンバ関数の戻り値のアドレスは違うのはどういうことでしょうか。 主な使い用途がありましたら、教えてください。

  • Javaのプログラミングにおいて、暗黙的にオブジェクトが生成される場合はどんな場合ですか?

    Javaアソシエイツの資格取得ため、勉強しています。詳しい解説を求めています。 ■問題 次のプログラムを実行すると、出力結果はどのようになりますか。1つ選択してください。 http://d.hatena.ne.jp/motoi20/20081210 ■解説 正解は選択肢Aです。func(s)では、変数sが参照しているStringオブジェクトを「func(Stirng s)」の引数sに渡しています。func()メソッドの処理で「s+"Hello"」という処理をしたとき、内部では暗黙的に新しいStringオブジェクトが生成されます(変数sに文字列を追加しているわけではありません。)func()メソッドの呼び出しが「s=func(s)」となっていた場合、main()メソッド内の変数sが新しくできたオブジェクトを参照するため、結果の出力は「JavaHello」になりますが、「func(s)」の呼び出しでは戻り値を再代入していないため、変数sは文字列「Java」を保持したオブジェクトを参照します。Stringクラスは読み取り専用オブジェクトであることに注意しましょう。 ■疑問 通常、オブジェクトを作成するのは、「new」を使って行うわけですよね?暗黙的にオブジェクトが生成されるのは、どういう場合でしょうか?読み取り専用オブジェクトだから何に気をつければいいのでしょうか?

専門家に質問してみよう