TIPS > requireの相互参照

requireの相互参照


  • 以下のようなrequireで相互参照するコードの実行例を示す

- x.rb
# x.rb
print "before require(x):"
p $"
require 'y'
print "after require(x):"                                                       
p $"

- y.rb
# y.rb
print "before require(y):"
p $"
require 'x'
print "after require(y):"                                                       
p $"

- 実行結果
# 実行結果
ruby x.rb
# => before require(x):[]
#    before require(y):[]
#    before require(x):[]
#    after require(x):[]
#    after require(y):["x.rb"]
#    after require(x):["x.rb", "y.rb"]

  1. x.rbを実行する
  2. x.rbでまだロードされていなかったのでy.rbがrequireされる
  3. y.rbでまだロードされていなかったのでx.rbがrequireされる
  4. x.rbでy.rbがrequireされるが、既にロードされているのでできない。

問題の発生するコード

  • 以下のコードだとa.rbがb.rbをrequireして、b.rbがa.rbをrequireした際にa.rbでb.rbがrequireされないためにエラーとなる。
    • 対策としては相互参照しないように設計するしかない?

- a.rb
# a.rb
require 'b'
 
class A
  def A.test
    B.output
  end  
 
  def A.output
    puts "test"
  end  
end
 
A.test

- b.rb
# b.rb
require 'a'
 
class B
  def B.test
    A.output
  end  
 
  def B.output
   puts "test"
  end  
end

- 実行結果
# 実行結果
# ruby a.rb 
# => ./a.rb:5:in `test': uninitialized constant A::B (NameError)
# from ./a.rb:13
# from ./b.rb:1:in `require'
# from ./b.rb:1
# from a.rb:1:in `require'
# from a.rb:1
最終更新:2011年02月22日 11:44