Rails

【Rails】module外のクラスを呼び出したい場合の対処方法【::を付ける】

Rails

 

今回はmodule外のクラスを呼び出したい場合の対処法についてまとめました。タイトルで全て完結している感がありますが、例を踏まえながらみていきます。

【事象】予期しないクラスが呼び出される

以下のようなUserクラスがあり、その中にinitializeメソッドが定義されると仮定します。この場合、User.newを実行すると「module外のinitialize」が出力されます。

# sample.rb

class User
  def initialize
    puts 'module外のinitialize'
  end
end

User.new
% ruby sample.rb
=> module外のinitialize

 

続いて、同名のクラス名を持ち一方がmoduleで囲まれているとします。では、そのmodule内でUser.newを実行するとどうなるのでしょうか。

# sample.rb

class User
  def initialize
    puts 'module外のinitialize'
  end
end

module Admin
  class User
    def initialize
      puts 'module内のinitialize'
    end
  end

  User.new
end

 

この場合はmodule内のinitializeメソッドが実行され、「module内のinitialize」が出力されるようになります。次の項目では、このような場合にmodule外のinitializeメソッドを呼び出す方法についてみていきます。

% ruby sample.rb
=> module内のinitialize

【解決策】::(コロン2つ)を付ける

クラス名の始めに::(コロン2つ)を付けることで、module外のクラスを呼び出すことができます。先程の例では、User.new::User.newにすることで解決できます。

class User
  def initialize
    puts 'module外のinitialize'
  end
end

module Admin
  class User
    def initialize
      puts 'module内のinitialize'
    end
  end

  ::User.new
end
% ruby sample.rb
=> module外のinitialize

 

このように::(コロン2つ)は、モジュールやクラス内で定義された定数名を外部から参照するときに使用されます。

まとめ

  • 同名のクラス名を持ち一方がmoduleで囲まれ、module内でクラスを呼び出した場合、module内のクラスが呼び出される
  • クラス名の始めに::(コロン2つ)を付けることで、module外のクラスを呼び出すことができる

参考

ころんころんの話をしよう。もしくはモジュールの名前空間について。

 

 

今回はmodule外のクラスを呼び出したい場合の対処法についてまとめました。クラスを呼び出す際に想定した挙動にならない場合は、今回の事象を疑ってみても良いかもしれません。