プロが教える店舗&オフィスのセキュリティ対策術

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にしたいのですが
やり方が分かりません。

もし、良い方法があれば、ご教授お願い致します。

A 回答 (3件)

インスタンスそのものをnilに変える(?)というのではなく、名前の参照先をnilに変えるということですよね?


となると、その名前を何かしらの手段で入手する必要がありそうですが、どこまでを対象とされているのでしょうか。
また、newメソッド以外にもインスタンスを作成する可能性はありますが、newメソッド経由で作成された物に限るのでしょうか。

仮にグローバル変数かつインスタンス全てということであれば、こういった感じで実現できそうです。

https://ideone.com/Jpphp

(===はクラス判定に限らないことと、kind_of?はサブクラス等も含められる事に気をつけてください)

クラス変数や定数、現在のローカル変数等も同様に実現可能です。
ただ、それで対象のインスタンスすべてがGCによって攫われたのかと言われると、自分にもよくわかりません。
最後にObjectSpace経由で対象のインスタンスが無くなっている事を確認したほうがいいかもしれませんが・・・それでも全ての「組み込みクラスのインスタンス」まで含められるわけではない筈です。

ちなみに、どういった用途を想定されているのでしょうか?
    • good
    • 0
この回答へのお礼

sholmes様

ご回答ありがとうございます。
私が、知りたかった事はそれでした。

>インスタンスそのものをnilに変える(?)というのではなく、名前の参照先をnilに変えるということですよね?

今回の質問では、インスタンスをnilに変えようと思っていました。

その後で、GC.startをしたら、参照先も全部消えてくれるのではないかという予想でした。
もちろん、参照先も分かれば、それはそれで嬉しいです。

>また、newメソッド以外にもインスタンスを作成する可能性はありますが、
>newメソッド経由で作成された物に限るのでしょうか。

すみません、newメソッド以外でインスタンスを作成する方法が
あることを知りませんでしたので、この事は想定外でした。
今回の質問では、new経由で作成された物に限っていました。

式の意味は良く分かりませんでしたが(特にeval)
そのまま書きますと、上手くいきました。
式の意味の流れは、こんな感じだ予想しています。

全てのグローバル変数を見る。
もしそのグローバル変数が、クラスAのインスタンスなら、nilにする。

>それでも全ての「組み込みクラスのインスタンス」まで含められるわけではない筈です。
詳しくはないので間違ってるかもしれませんが、
もしかしたら、今問題にしていたのは、
組み込みクラスのインスタンスかもしれません。

>ちなみに、どういった用途を想定されているのでしょうか?
RPGツクールVXというゲーム作成ソフトに
Spriteというクラス(恐らくRPGツクール独自の組み込みクラス)
があるのですが、それを使って表示された画像を
一旦全部消したかったのです。

今回の質問は、解決できましたので
その用途については、ゆっくり調べて行きたいと思います。

お忙しい中、ありがとうございました。
今後とも宜しくお願い致します。

お礼日時:2011/09/24 21:57

>A.newで作られた物全てをnilにしたいのですが



そんなことをしたいと思ったこと自体が間違っている可能性がありますね。
普通はそんなことはしません。
なぜそんなことを思ったのでしょうか?
    • good
    • 0
この回答へのお礼

notnot様

ご回答ありがとうございます。

>そんなことをしたいと思ったこと自体が間違っている可能性がありますね。
その可能性は、かなりあると思います。

>なぜそんなことを思ったのでしょうか?

この掲示板と少し話題が外れてしまうようで心苦しいのですが
やりたい事の大筋は、前述の通りなのですが
もう少し深く掘り下げますと
ゲームにあらかじめ用意されているスクリプトと
他人の作ったスクリプトを利用している為
スクリプトに詳しくない私には、
他人が作ったスクリプトで表示している画像を消す事が出来ませんでした。

クラスAでSprite.newして作った画像を
クラスBから消す必要があったのですが
どちらのクラスも、別々のクラスを継承しているため
継承する事によって、別のインスタンスを参照し、nilにすることは諦めました
(出来るのかも知れませんが無理でした)

次に試したのが、クラスメソッドです。
クラスメソッドを使って、クラスBからクラスAのメソッドを使う事はできたのですが
クラスAの変数を利用することはできませんでした。

その為、変数をグローバル変数して、クラスBからクラスAの変数を使える様にしました。

しかし、何故か、グローバル変数にしたにも関わらず、クラスA内でSprite.newした画像を
クラスBから、全て消す事が出来なかったのです。
消えるときもありますし、時間がたってから消える事もあります。

とにかく、訳がわからないので、全部消したらどうなるか?
という事をやってみたかったのです。

お忙しい中、ありがとうございました。
今後とも宜しくお願い致します。

お礼日時:2011/09/24 21:59

まず定義した変数名を調べます。


グローバル変数だと
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
}
こんな感じでしょうか
    • good
    • 0
この回答へのお礼

ki073様
ご回答ありがとうございます。

>ところで、グローバル変数である必要があるのでしょうか?
今直面している問題と条件が同じですので
グローバル変数であった方が望ましいです。

global_variablesは便利ですね。
初めて知りました。
今後、何かに使えそうです。

教えて頂いた方法は、自分で把握している物を
あとから消しているので、
少し私の意図してることとは違いましたが
この方法も、便利ですね。

式の意味は良く分かりませんでしたが
その通りに書くと、消す事ができました。

お忙しい中、ありがとうございました。
今後とも宜しくお願い致します。

お礼日時:2011/09/24 21:56

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!