2013-12-08 15 views
5

私は非常に奇妙なエラーがあります私は私の頭を包み込むことはできません。クラスが必要ですがアクセスできません

基本的に、私は私のlibフォルダにこのクラスを持っている:

# lib/api/amazon.rb 
module API 
    class Amazon 
    ... 
    end 
end 

私はどこかでそれを使用したい場合は、私はそれをrequire

require 'api/amazon' 
API::Amazon.do_stuff 

これが最初に動作しますが、しばらくした後、それが壊れますNameError: uninitialized constant API::Amazonを発生させます。私がこれをデバッグし、エラーが発生したときにファイルを再度requireにしようとすると、ファイルがすでにロードされたことを示すfalseを返します。私は$"(これはロードされたファイルのリスト)でも見ることができます。なぜAPI::Amazonにアクセスできないのですか?

注:私は "API" を使用する必要はありません理由であるActiveSupport::Inflectorに頭字語として "API" を追加しました:

# config/initializers/inflections.rb 
ActiveSupport::Inflector.inflections do |inflect| 
    inflect.acronym 'API' 
end 

はEDIT:

私は同じ、同様::API::Amazon.do_stuffを試してみました結果。

+0

'ActiveSupport'は時々、ネストされたクラスのいくつかのクリーンアップを実行して、dinamically createdを削除しているようです。これは、誰かが 'class_eval'のようなメソッドで動的なクラス拡張を使用する場合に必要となるかもしれません。 – mudasobwa

+0

@mudasobwaというのは、それが何を意味するのか正確には分かりません。私は動的な 'class_eval'のものは使用しません。動的またはメタプログラミングの魔法がない通常のクラスです。 –

+0

あなたは既に存在する(そして凍結された、[その政治](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html))モジュールに合わせてクラスを定義します。たとえば、ActiveSupport :: Inflectorをmonkeypatchedしているとします。 'ActiveSupport'は一旦ロードされると、**それは**ネストされたクラスでそのようなクリーンアップを実行するかもしれません。 – mudasobwa

答えて

1

私はあなたと同じ結果を得るためにいくつかのコードを書いています。多分それはいくつかの手がかりを与えることができます。

trytemp.rb:それが最初にうまく機能

module API 
    class Amazon 
    def hello 
     puts "API::Amazon initially works well" 
     $stdout.flush 
    end 
    end 
end 

s = API::Amazon.new 
s.hello 

p API.constants 
API = Module.new 
p API.constants # Here you can see constant Amazon disappers from module API 
s = API::Amazon.new 
s.hello 

は、その後、同じエラーを取得し、 "初期化されていない一定のAPI ::アマゾン(NameError)":

$ ruby trytemp.rb 
API::Amazon initially works well 
[:Amazon] 
trytemp.rb:15: warning: already initialized constant API 
[] 
trytemp.rb:19:in `<main>': uninitialized constant API::Amazon (NameError) 
+0

あなたのコードに間違いがあります(私が間違っていれば私を修正してください)。モジュール(Module.new)ではなくクラスのみを初期化できます。 –

+0

@ maro30。あなたは本当に間違っています。あなたは、モジュールとモジュールのインスタンスを混同しています。たとえば、APIはModuleのインスタンスです。言い換えれば、モジュールはクラスであり、APIはモジュールです。 – uncutstone

+0

ok大文字の「M」の「モジュール」はどこから来たのですか? 'API'がそのインスタンスである場合、' Module'はクラスとみなされます。ちょうどあなたのコードを理解しようとしています... –

0

EDIT:

私は答えを見つけましたが、同じエラーがちょうど再び発生しました... :(

終了編集

@uncutstoneの助けを借りて答えが見つかったようです。

はそうのように、私はAPI::Amazonのためだけでなく、いくつかのコントローラのAPI名前空間を使用していなかったが判明:

# app/controllers/api/v1/accounts_controller.rb 
class API::V1::AccountsController < APIController 
    ... 
end 

私の理論は、これらのコントローラの1時間と再でいくつかの時点で自動的にリロードされたということですモジュール/名前空間のAPIを初期化して(したがってクリアします)。 したがって、API::Amazonは利用できませんでしたが、require ing lib/api/amazon.rbは既に必要であったため再度読み込まれなかったため役に立たなかった。 私はこのように見えるようにコントローラを変更:

# app/controllers/api/v1/accounts_controller.rb 
module API 
    class V1::AccountsController < APIController 
    ... 
    end 
end 

をし、今では正常に動作するようです。

+0

これは/これが開発上の問題であるように見えます。 –

関連する問題