2017-03-18 9 views
0

私は別のファイルで宣言したモジュールにアクセスする際に問題があります。概念的にこの権利があるのでしょうか?私に説明させてください。Requireの範囲

だから、a -> b -> cそう

ファイル

module HelloWorld 
    def greet 
    "hello world" 
    end 
end 

ファイルB

require "a" 

ファイルC

require "b" 
include HelloWorld 

puts greet 

をだように私は、b、cのセットアップを提出した場合、これは作業?何かを変更

今、私はそれを行う場合は、この方法

ファイル

module HelloWorld 
    def greet 
    "hello world" 
    end 
end 

ファイル

include HelloWorld 

puts greet 

BファイルC

require "a" 
require "b" 

でしょうか?一度必要とされる宝石はどんなファイルでもアクセス可能ですが、2番目のシナリオではモジュールへのアクセスに問題があります。どんな助けもありがとうございます。

更新:私は両方のシナリオをテストしましたが、両方とも動作します。これは概念的な問題ではなく、自分のコードのバグであると私を信じさせます。私はプロジェクトのデバッグに取り組んでいます。

+0

(ディレクトリSITが$LOAD_PATHに追加されたり、代わりに require_relativeを使用するかのように長い として)動作します答えの一つに指摘したコードにバグがあります。私は要求に '。/'をつけなかった。 –

答えて

1

私はあなたのコードを実行しようとすると、私は単にそれがa.rbファイル、その後上昇し、LoadError例外を見つけることができない、それはKernel's require method を使用していることを言っている、次のエラーメッセージ

$ ruby c.rb 
~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- a (LoadError) 
    from /Users/Sonna/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' 
    from c.rb:2:in `<main>' 

を取得します。あなたはKernal's require_relative method

require_relative "a" 
require_relative "b" 

を使用することができますし、それがcファイルへの相対それらa & bファイルするファイルを必要とするために

それとも、彼らのカスタムスクリプトをロードするためにRubyの宝石で使用 一般的な慣例であるあなたのc.rbファイルに次のコード行を追加することができます/ライブラリ

current_directory = File.expand_path("../", __FILE__) 
$LOAD_PATH.unshift(current_directory) unless $LOAD_PATH.include?(current_directory) 

これはからカレントディレクトリ../が追加されます現在のファイル__FILE__, は、それを上記のカレントディレクトリの絶対パスに拡張し、それを既存のロードパスグローバル変数に追加します。例えば内部的には

$ ruby c.rb 
hello world 

次私は再びあなたのコードを実行すると

If the filename does not resolve to an absolute path, it will be searched for in the directories listed in $LOAD_PATH ($:) .

-- Kernel's require method

は、だから私は見 絶対パスに指定されていない場合は、ファイル名で検索に使用require

puts $LOAD_PATH 
# => ["~/Projects/ruby/stackoverflow_questions/the_scope_of_require", 
#  "/usr/local/Cellar/rbenv/1.0.0/rbenv.d/exec/gem-rehash", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0/lib", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0/x86_64-darwin15", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/site_ruby", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby/2.3.0", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby/2.3.0/x86_64-darwin15", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/vendor_ruby", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/2.3.0", 
#  "~/.rbenv/versions/2.3.1/lib/ruby/2.3.0/x86_64-darwin15"] 

注目すべきは、

A file will not be loaded again if its path already appears in $" . For example, require 'a'; require './a' will not load a.rb again.

-- Module: Kernel (Ruby 2_4_0)

requireメソッドのうちの1つが、そのファイルが呼び出されるメソッドの1つになる前に一度発生している限り、それは動作するはずです。ので、あなたの例の両方が

+0

1分前に実際に気づいたことがあります。 [これは実際のコードです](https://github.com/space-hanger/apollo-8)。ですから、私は 'app/controllers/application_controller.rb'を持っていて、' require "./app/helpers/helpers"と 'require" ./app/models/user "'の両方を持っています。アプリケーションコントローラの 'app/helpers/helpers'からモジュールにアクセスしようとすると動作しますが、' app/models/user'から試してみると失敗します。私はそれを 'require" ./app/helpers/helpers "'を 'app/models/user'に追加することで修正しましたが、これを行う必要はありません。概念的には、シナリオbに一致します。 –

+0

申し訳ありません私はたぶん質問に元のソースコードを載せておくべきでした。 –

+0

サンプルアプリケーションコードを見ると、 'send_text'ヘルパーメソッドがあなたの記述する痛みの原因となっているようです。私は "あなたがUserモデル(特にモデルがまだ保存されていない場合)に 'phone'属性を設定するたびにSMSを送信することをお勧めしますか?"また、再送信検証コードではすでに 'send_text'を使用しているようですが、APIの代わりにユーザーコントローラアクションの作成または更新(ユーザーフォームオブジェクトの保存メソッドで、使い慣れている場合)モデルからの呼び出し。それは本当に依存し、アプリケーション内でどこから呼び出すかはあなた次第です。 – sonna