Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to "import" nested classes into current class in Ruby?

In Ruby I can nest modules/classes into other modules/classes. What I want is to add some declaration inside file or class to be able to refer nested classes by their short names, e.g. to use Inner to get Outer::Inner, like you would have in Java, C# etc. The syntax might be like this:

module Outer
  class Inner; end
  class AnotherInner; end
end
class C
  import Outer: [:Inner, :AnotherInner]
  def f
    Inner
  end
end

The simplistic implementation could be like this:

class Class
  def import(constants)
    @imported_constants = 
      (@imported_constants || {}).merge Hash[
        constants.flat_map { |namespace, names|
          [*names].map { |name| [name.to_sym, "#{namespace}::#{name}"] }
        }]
  end

  def const_missing(name)
    const_set name, eval(@imported_constants[name] || raise)
  end
end

Is there solid implementation in Rails or some gem, that does similar importing while compatible with Rails' mechanism of auto-loading?

like image 432
Alexey Avatar asked Aug 09 '12 20:08

Alexey


1 Answers

module Outer
  class Inner; end
  class AnotherInner; end
end

class C
  include Outer

  def f
    Inner
  end
end

C.new.f # => Outer::Inner

Remember: there is no such thing as a nested class in Ruby. A class is just an object like any other object, and it gets assigned to variables just like any other. In this particular case, the "variable" is a constant which is namespaced inside a module. And you add that constant to the namespace of another module (or class) the same way you would any other constant: by includeing the module.

like image 72
Jörg W Mittag Avatar answered Oct 25 '22 06:10

Jörg W Mittag