• ベストアンサー

あるクラスの全てのインスタンスをnilにする方法

class A def sample p"サンプル" end end $a = A.new $a.sample $b = A.new $b.sample $c = A.new $c.sample この時、$aをnilにする時 $a = nil とすれば良いのですが $a、$b、$c・・・のように複数あって どれだけあるか分からない条件下で A.newで作られた物全てをnilにしたいのですが やり方が分かりません。 もし、良い方法があれば、ご教授お願い致します。

  • Ruby
  • 回答数3
  • ありがとう数4

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

  • ベストアンサー
  • sholmes
  • ベストアンサー率81% (89/109)
回答No.2

インスタンスそのものをnilに変える(?)というのではなく、名前の参照先をnilに変えるということですよね? となると、その名前を何かしらの手段で入手する必要がありそうですが、どこまでを対象とされているのでしょうか。 また、newメソッド以外にもインスタンスを作成する可能性はありますが、newメソッド経由で作成された物に限るのでしょうか。 仮にグローバル変数かつインスタンス全てということであれば、こういった感じで実現できそうです。 https://ideone.com/Jpphp (===はクラス判定に限らないことと、kind_of?はサブクラス等も含められる事に気をつけてください) クラス変数や定数、現在のローカル変数等も同様に実現可能です。 ただ、それで対象のインスタンスすべてがGCによって攫われたのかと言われると、自分にもよくわかりません。 最後にObjectSpace経由で対象のインスタンスが無くなっている事を確認したほうがいいかもしれませんが・・・それでも全ての「組み込みクラスのインスタンス」まで含められるわけではない筈です。 ちなみに、どういった用途を想定されているのでしょうか?

hourensan
質問者

お礼

sholmes様 ご回答ありがとうございます。 私が、知りたかった事はそれでした。 >インスタンスそのものをnilに変える(?)というのではなく、名前の参照先をnilに変えるということですよね? 今回の質問では、インスタンスをnilに変えようと思っていました。 その後で、GC.startをしたら、参照先も全部消えてくれるのではないかという予想でした。 もちろん、参照先も分かれば、それはそれで嬉しいです。 >また、newメソッド以外にもインスタンスを作成する可能性はありますが、 >newメソッド経由で作成された物に限るのでしょうか。 すみません、newメソッド以外でインスタンスを作成する方法が あることを知りませんでしたので、この事は想定外でした。 今回の質問では、new経由で作成された物に限っていました。 式の意味は良く分かりませんでしたが(特にeval) そのまま書きますと、上手くいきました。 式の意味の流れは、こんな感じだ予想しています。 全てのグローバル変数を見る。 もしそのグローバル変数が、クラスAのインスタンスなら、nilにする。 >それでも全ての「組み込みクラスのインスタンス」まで含められるわけではない筈です。 詳しくはないので間違ってるかもしれませんが、 もしかしたら、今問題にしていたのは、 組み込みクラスのインスタンスかもしれません。 >ちなみに、どういった用途を想定されているのでしょうか? RPGツクールVXというゲーム作成ソフトに Spriteというクラス(恐らくRPGツクール独自の組み込みクラス) があるのですが、それを使って表示された画像を 一旦全部消したかったのです。 今回の質問は、解決できましたので その用途については、ゆっくり調べて行きたいと思います。 お忙しい中、ありがとうございました。 今後とも宜しくお願い致します。

その他の回答 (2)

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.3

>A.newで作られた物全てをnilにしたいのですが そんなことをしたいと思ったこと自体が間違っている可能性がありますね。 普通はそんなことはしません。 なぜそんなことを思ったのでしょうか?

hourensan
質問者

お礼

notnot様 ご回答ありがとうございます。 >そんなことをしたいと思ったこと自体が間違っている可能性がありますね。 その可能性は、かなりあると思います。 >なぜそんなことを思ったのでしょうか? この掲示板と少し話題が外れてしまうようで心苦しいのですが やりたい事の大筋は、前述の通りなのですが もう少し深く掘り下げますと ゲームにあらかじめ用意されているスクリプトと 他人の作ったスクリプトを利用している為 スクリプトに詳しくない私には、 他人が作ったスクリプトで表示している画像を消す事が出来ませんでした。 クラスAでSprite.newして作った画像を クラスBから消す必要があったのですが どちらのクラスも、別々のクラスを継承しているため 継承する事によって、別のインスタンスを参照し、nilにすることは諦めました (出来るのかも知れませんが無理でした) 次に試したのが、クラスメソッドです。 クラスメソッドを使って、クラスBからクラスAのメソッドを使う事はできたのですが クラスAの変数を利用することはできませんでした。 その為、変数をグローバル変数して、クラスBからクラスAの変数を使える様にしました。 しかし、何故か、グローバル変数にしたにも関わらず、クラスA内でSprite.newした画像を クラスBから、全て消す事が出来なかったのです。 消えるときもありますし、時間がたってから消える事もあります。 とにかく、訳がわからないので、全部消したらどうなるか? という事をやってみたかったのです。 お忙しい中、ありがとうございました。 今後とも宜しくお願い致します。

  • ki073
  • ベストアンサー率77% (491/634)
回答No.1

まず定義した変数名を調べます。 グローバル変数だと global_variables で定義されている変数名が得られます。ところが最初からシステムで定義されているものが多くありますので、それを取り除く必要があります。 ところで、グローバル変数である必要があるのでしょうか? 特に理由がないのでしたら、ローカル変数(変数名が小文字の英文字から始まる)にしましょう。 ローカル変数名は local_variables で得られます。初めて気がついたのですが"_"が最初から定義されているのですね。(これは何に使うのだろう??) local_variables-["_"]で定義された変数名を取得できます。 もっと簡単そうなのは配列に入れることです。例えば a[0]=A.new a[1]=A.new とかの様に そうすると a=a.collect{|v| A===v ? nil : v} で可能です。 またローカル変数の場合は (local_variables-["_"]).each{|v| if A===eval(v) eval(v+"=nil") end } こんな感じでしょうか

hourensan
質問者

お礼

ki073様 ご回答ありがとうございます。 >ところで、グローバル変数である必要があるのでしょうか? 今直面している問題と条件が同じですので グローバル変数であった方が望ましいです。 global_variablesは便利ですね。 初めて知りました。 今後、何かに使えそうです。 教えて頂いた方法は、自分で把握している物を あとから消しているので、 少し私の意図してることとは違いましたが この方法も、便利ですね。 式の意味は良く分かりませんでしたが その通りに書くと、消す事ができました。 お忙しい中、ありがとうございました。 今後とも宜しくお願い致します。

関連するQ&A

  • 別のクラスのインスタンスの作り方

    現在、javaからrubyに移行するために勉強しているのですが、別のファイルに定義したクラスのインスタンスが作成できなくて、困っています。 具体例をあげると require './B' class A end def initialize b = new B end end --別のファイル class B def initialize p 'hello' end  public : initalize end こんな2つのファイルがあったとして、Aのインスタンスを作成すると、 undefined method `B’ というエラーがでます。 私としてはこのエラーの原因がinitializeがデフォルトでprivate宣言なのが原因だと考えているのですが、publicと指定してもエラーとなることから、いくつか疑問が湧いたので質問させていただきます。 1、そもそもBクラスのインスタンスが作成できないのはinitializeがデフォルトでprivate宣言なのが原因なのか? 2、1があっていたと仮定するとBクラスのinitializeをpublic指定しているのになぜ呼び出せないのか? 3、rubyはなぜデフォルトでinitializeがprivateなのか?(javaではコンストラクタをprivateにするということは普通はしない。使うときはシングルトンやUtilのようなクラスを作るときに限る) 以上です。よろしくお願いします。

    • ベストアンサー
    • Ruby
  • 【vb.net】クラス化について

    大学で以下のような練習問題を頂きました。 ----- Public Sub test()  Dim a As b = New c  Dim i As Integer = 1  a.disp(i) End Sub 問:この時のbとcを実装せよ。 ----- Public Class c  Public Function disp(ByVal i As Integer) As String   return "iは" & i & "です"  End Function End Class までは書いてみたのですが、b の扱いがどうもわかりません。 どなたか教えていただけませんでしょうか。

  • 【ruby】特異クラスを使って,File.statをカスタムしたい

    File.statに、nameというメソッドを追加したいです。 st=File.stat('hoge.txt') puts st.name #=> hoge.txt 上記のように使いたいのです。 そこで、以下の様に書いてみました。(行頭のスペースは全角です) class File  class << self   def stat(file)    st=File::Stat.new(file)    class << st     def name      @file     end    end    st   end end end st=File.stat('./hoge.txt') puts st.name #=> nil 上記実行結果はnilが出力され、期待した結果は得られませんでした。 上記の様に書いた理由を以下に記します。 クラスメソッドstatは、file.rbのclass Fileの中に定義されていて、 stat.rbのFile::Stat.new(file)を戻り値としていました。 stat.rbのclass File::Statのinitializeでは、 def initialize(file)  @file = file  (略) end となっていたので、上記の様に書いてみたのですが、何が悪いのでしょうか? ご指導のほど、宜しくお願いいたします。

    • ベストアンサー
    • Ruby
  • Rubyのプログラム

    今、サンプルとしてこれがあるんですけど、これは交点を出力するものなんですが、線を出力するにはどこを変えればよいですか?? Xみたいに線を描きたいです。 class Ten def initialize(x, y) @x = x # インスタンス(@がついているもの)変数に代 入 @y = y # インスタンス(@がついているもの)変数に代入 end attr_accessor :x, :y end class Sen def initialize(p1, p2) @p1 = p1 @p2 = p2 @a = (p2.y - p1.y)/(p2.x - p1.x) @b = -@a * p1.x p1.y end attr_accessor :p1 # 始点 attr_accessor :p2 # 終点 attr_accessor :a # 傾き attr_accessor :b # Y軸との交点 end def koten(l1, l2) x = (l1.b - l2.b)/(l2.a - l1.a) y = (l1.a * l2.b - l1.b * l2.a)/(l1.a - l2.a) puts x, y end p1 = Ten.new(0.0, 0.0) p2 = Ten.new(6.0, 4.0) p3 = Ten.new(0.0, 4.0) p4 = Ten.new(6.0, 0.0) l1 = Sen.new(p1, p2) l2 = Sen.new(p3, p4) koten(l1, l2)

  • クラスインスタンスとクラス型変数の配列

    C++からシフトしてきた若輩JAVAプログラマですが、微妙に理解しきれない部分があるため、お知恵をお借りしにきました。 最初にC++のサンプルを書かせていただきます。 ----- C++ ----- class Hoge {  /* 実装省略 */ } int main( void ) {  Hoge *hoge = new Hoge ;  Hoge *hoge = new Hoge[10] ; } --------------- これをJAVAで実装した場合、以下のようになると思います。 ----- JAVA ----- class Hoge {  /* 実装省略 */ } class Test {  public static void main( String[] args )  {   Hoge hoge = new Hoge() ; /* 1 */   Hoge[] hoge = new Hoge[10] ; /* 2 */  } } --------------- JAVAの場合、2ではクラスのインスタンスが確保されていないことを知りました。C++ではnewの役割が「何かをメモリ上に確保する(malloc)」という意味合いであったのに対し、JAVAの場合は考え方が違うものだということでしょうか。 そうすると、 int[] a = new int[10] ; と、 Hoge[] hoge = new Hoge[10] ; のnewは、意味が違うという認識にたどり着いてしまうのですが、そうなると『妙な』気持ちがしてしまいます。そんな面倒な言語仕様では無い気もしますし。 私の考え方が間違っている可能性が高いと思いますので、教唆していただけると助かります。 よろしくお願いします。

    • ベストアンサー
    • Java
  • 演算子の再定義とインスタンス変数の参照と代入

    list9.1とlist 9.3をあわせた二次元の座標、xとyを持つ プログラムです class Point attr_reader :x, :y def initialize(x=0, y=0) @x, @y = x, y end def inspect # 表示用 "(#{x}, #{y})" end def +(other) # x、yのそれぞれを足す self.class.new(x + other.x, y + other.y) end def -(other) # x、yのそれぞれを引く self.class.new(x - other.x, y - other.y) end def [](index) case index when 0 x when 1 y else raise ArgumentError, "out of range `#{index}'" end end def []=(index, val) case index when 0 self.x = val when 1 self.y = val else raise ArgumentError, "out of range `#{index}'" end end end point = Point.new(3, 6) p point[0] #=> 3 p point[1] = 2 #=> 2 p point[1] #=> 2 p point[2] #=>エラー(ArgumentError) についてお尋ねしたいのですが、 def [](index)で演算子を再定義する際、値を参照する方法で def [](index)  case index  when 0   x   : と、していますが、xp.135のアクセサの説明など では@xと「@」が要りそうな感じがするのですが、この 場合は省いて大丈夫なんでしょうか? プログラムがローカル変数と間違って処理したりという ことは無いんでしょうか。 仮にないとすれば、ここのcase文にはインスタンス変数 と同じ名前のローカル変数などは定義できないのでしょうか? ご教授願います。

    • ベストアンサー
    • Ruby
  • Ruby インスタンスの初期化について

    newメソッドを使わずにinitializeメソッドを定義しただけで インスタンスが作成されて初期化までされる理屈について 教えていただけないでしょうか? またクラスを作るときに基となっているObjectクラスとは一体 何物なのか、教えて頂きたい。 例 01:#Sampleクラスを作る 02:class Sample 03: #Samlpeクラスのインスタンスを初期化 04: def imitialize( lv, hp ) 05: end 06:end ↑の場合インスタンスlvとhpは、「lv = sample.new( 0 )」などと言う ように定義されてない。 それにnewメソッドでインスタンスを作りそこに数値の0を代入できるなら そもそもinitializeで初期化する必要は無いのではないでしょうか? 有識者の方いらっしゃいましたら、ご説明をよろしくお願いします。

    • ベストアンサー
    • Ruby
  • 内部クラスから別の内部クラスのインスタンスを取得するには

    早速ではございますが質問をさせていただきます。 以下のクラスで、 ////////////////////////////////////////////////// class A { class B {} class C {} } ////////////////////////////////////////////////// 内部クラスB内で内部クラスCのインスタンスを取得するに はどうすればよいのでしょうか?どうかご教授のほど よろしくお願いします。

    • ベストアンサー
    • Java
  • インスタンス変数の特殊な参照

    次のようなクラスを考えたときに(特に意味があるものではないですが) class A{ int a; A(){ a = 10; B b = new B(); } } class B{ int b; B(){ b = 20; C c = new C(); } } class C{ int c; C(){ c = 20; } } Cのコンストラクタの中から、Aのインスタンス変数aやBでのbの値を 参照することって出来ないのでしょうか? 変数をクラス変数にする、引数として渡す以外の方法を探しています。

  • 【ruby】 『クラスの生成に失敗』を表現したい

    『クラスの生成に失敗』を表現したいのです。 newの戻り値にnilやfalseを返せばよいと考え、 以下の様に書いてみました。(行頭は全角スペースです。) class Hoge  def initialize(arg)   return arg  end end h = Hoge.new(false) STDERR.puts 'err' unless(h) errはputsされませんでした。(グーグルで調べるとinitializeのreturnは、返ってこないそうでした。) そこで以下の様に書きました。(行頭は全角スペースです。) class Hoge  attr_reader :stat  def initialize(arg)   @stat = arg  end end h = Hoge.new(false) STDERR.puts 'err' unless(h.stat) なんか、ものすごく我流になってる気がします。。。 アドバイスをお願いいたします。

    • ベストアンサー
    • Ruby