2012-01-04 5 views
2

Rubyでは、MyClassのインスタンスを作成するクラスの名前を取得する方法はありますか?私のクラスを "新しくした"クラスの名前

私はinitializeメソッドの引数として渡すことができますが、MyClassのインスタンス内にMyClassのインスタンスを作成したクラスと関係があるデータが既にあるかどうかを知りたいと思います。

だから、それは一般的に

class MyClass 
    def initialize 
    @who_called_me = who_called_me.name 
    end 

    def who_called_me 
    puts @who_called_me 
    end 
end 
+6

これを知る必要がある場合は、おそらくデザインに問題がある可能性があります。 –

+2

一般的に、私はこれを行う簡単な方法がないと考えることができます。しかし、スタックバックトレースの文字列を取得し、 'new'を呼び出す前にそのフレームを解析することができます。それは 'new'と呼ばれるコードの一部を与えるかもしれません。しかしそれはあなたのコードをスタックバックトレースのフォーマットに依存させるでしょう。良いことではありません。 – Linuxios

+0

これは特別なケースですが、私のデザインに疑問を呈してくれてありがとう、本当に助かります –

答えて

5

これは実装やバージョン間で移植性がありませんが、これは粗溶液である:

who_made_me=caller[3].split(':')[1][4..-2] 

これが何をするか、それは、その後、現在のスタックを取得しinitializeallocate、およびnewの文字列をスキップし、そしてありますメソッド名を文字列から取得します。繰り返しますが、これはトータルのハックであり、不特定の動作に基づいています。 絶対にが必要な場合を除き、私はこれを使用することをお勧めしません。

+0

あなたは男です!これはいくつかのコードが混乱していますが、それがそれほど価値があることを心配しないでください。いくつかの人々は、ロボットでフレンドリーなコンプをしています。私は自分のクラスを作成することから自分のクラスを保護する必要があるとしましょう。 –

+0

うれしいです!それはうんざりですが、それがうまくいくならば、素晴らしいです! – Linuxios

+1

@Lorenでは、あなたを作成している他のクラスから確実に保護することはできません。なぜなら、ルビーでは、クラスを再オープンすることによって、保護するクラスの部分を書き換えることができるからです。 – JasonTrue

1

ようになり、これは悪です。私はC#で同等のものを見たことがありますが、それはひどく残酷な副作用を生みました。

本当にこれをやらなければならないのであれば、おそらくKernel.callerで始めるでしょう。しかし、しないでください。

+0

私は* Kernel#callerを使って*動作する可能性のあるものを投稿しました。それは完全なハックです、私はあなたに同意しますが、それは答えです。 – Linuxios

+1

「暴力的に残酷な副作用」 - もっと教えてください! –

+0

@Andrew、基本的には、他のコードがコンストラクタの動作を予測できなかったため、特別なケースがあったため、すべてのOOPルールが破られました。 Perlでは、呼び出し元によってパラメータが異なるように解析されたさらに悪い例を見てきました。 – JasonTrue

関連する問題