LoginSignup
4
3

More than 5 years have passed since last update.

Rubyで名前空間が定義されているか確認する方法

Posted at

Rubyで名前空間が定義されているか確認する方法を調べている際、色々試した結果をメモしておきます。

方法1.Objectに対してconst_defined?を実行して調べる

これは駄目な方法。

method1.rb
module Hoge
  module Foo
  end
end

# 名前空間の書式で定数定義されている訳ではないので駄目.
puts Object.const_defined?("Hoge::Foo")
実行結果
method1.rb:7:in `const_defined?': wrong constant name Hoge::Foo (NameError)
        from method1.rb:7:in `<main>'

方法2.defined?で定義済みか確認する

これは素直で良い方法。

method2.rb
module Hoge
  module Foo
  end
end

# 良い方法だが、名前空間を文字列でしか知らない場合に対応できない.
puts defined?(Hoge::Foo)
puts defined?(Hoge::Foo::Bar)
実行結果
constant

# `Hoge::Foo::Bar` は定義されていないので空文字列が返る

だが、仮に名前空間の情報が文字列でしか与えられていない場合、これでは対応できない。

方法3.名前空間を上から順番に定数定義されているかconst_defined?で調べる

ほぼほぼ無い要求かと思われるが、自分の場合、名前空間の情報を文字列でしか受け取ることができず、方法2を採用することができなかった。
そこで実施した苦肉の策が以下。

method3.rb
require "active_support"
require "active_support/core_ext"

module Hoge
  module Foo
  end
end

def defined_namespace?(full_namespace)
  search_namespace = Object
  full_namespace.split("::").each do |name|
    return false unless search_namespace.const_defined?(name)
    search_namespace = "#{search_namespace}::#{name}".constantize
  end
  true
end

puts defined_namespace?("Hoge::Foo")
puts defined_namespace?("Hoge::Foo::Bar")
実行結果
true
false

名前空間の定数を上から順番になめることで、定義されている名前空間か調べている。
これならば、文字列で名前空間の情報が与えられるケースでも対応することができる。

かなりレアケースかと思われるが、自分がまたハマった時のためにメモ。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3