2017-02-26 1 views
0

Ruby 2.1.7とRails 4.0.2リロード前に宣言されたオブジェクトを参照する! RailsのコンソールでArgumentErrorが発生する

rails consoleで作業している間。コンソールでObjectを宣言している場合、私はそれを見ました。コールよりもリロード!他のクラスのインスタンスを作成するコードでその同じオブジェクトのメソッドを呼び出すと、エラーが発生します。

ArgumentError:Firstのコピーがモジュールツリーから削除されましたが、まだアクティブです!

例を理解する方がはるかに簡単です:私はクラスに宣言する私のアプリ/モデルフォルダ内の

アプリ/モデル/ first.rb

class First 
    def foo 
    Second.new 
    end 
end 

アプリ/モデル/秒私はこれを実行したコンソールに比べ.RB

class Second 
end 

コマンド:

私は例外をGET以外
x = First.new 
reload! 
x.foo 

あなたは、なぜこの出来事がある説明を与えることはできますか?再読み込みの前に宣言された参照を使用するのは誤りですか?例外は良いことだと私は回避策を見つけることを試みるべきではないか、それは私のコードや構成の何かが、私はこの質問を持っている

間違っていることを示しています。 A copy of xxx has been removed from the module tree but is still active

一つの解決策は、余分に追加することでした::私はこの使用している場合、実際のプレフィックスとして:

::Second.new 

を、私は例外を取得していない

は、このソリューションを使用することは良いことであるか、あまりハックではなくRubyの道であることを、あなたと思いますか?

これが原因でエラーが発生しない理由を説明できますか?

答えて

1

これは、Railsの自動ロードが不足しているためです。例:
1. "Second"を使用すると、Railsは最初に "First"モジュールの定数であると想定し、古いモジュールを使用しないようにするために、 "First"という名前のモジュールが実際に存在するかどうかをチェックし、 「First」はまだオートロードされていないため、例外が発生します。
=>あなたの場合、xは使用時にすでに定義されているクラスのインスタンスにする必要があります。
2. ":: Second"を使用すると、Railsはトップレベルで、 "Second"定数を正常に解決します。
=>悪いことだと思います
私は酒田に同意しますので、回避策を見つけるべきではありません。

+0

ありがとう。私は私の例だけでモジュールを使用しなかったので、あなたが意味することは私には少し不明です。また、あなたの答えから、Firstはそれが使用されたらSecondへの参照を保持しているようです。この魔法はどうやって起こるの? –

+0

**ありがとうございます。私の例ではモジュールを一切使っていませんでしたので、あなたが意味することは少し不明です** ** 私の説明で意味することは、「ファースト」クラスです。ところで、ClassのスーパークラスはModuleです。 –

+0

**また、あなたの答えから、Firstは一度使用されるとSecondへの参照を保持しているようです。この魔法はどうやって起こるのですか?** 「最初に第2の参照を保持する」とはどういう意味なのでしょうか?x.fooを呼び出すと、Rubyはコードを実行し、未知の定数名 "Second" "const_missing"はRailsが入っている場所で、このメソッドをオーバーライドして不足している定数を自動ロードします。レールのオートロードの詳細については、 "http://urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/"を参照してください。 –

1

コンソール環境をリロードして、それ以前に作成したインスタンスを参照しようとするのは良いことではないようです。だから私はあなたがそれの回避策を見つけるべきではないと思う。

+1

ありがとう私は少し受け入れる前に他の答えがない場合は少し待つ –

関連する問題