I have a module B which gets mixed in to a module I, like this: module B BC = 4711 def g puts 'works' end end module I extend self extend B def f g puts B::BC end end If I invoke I.f I get the output works 4711 as expected. From I::f, I can invoke g directly, as if it had been defined inside I, because I included B using extend B. For accessing the constant BC, I have to qualify it explicitly, B::BC. Is there a way I can access the constants in B from within I without qualification with the module name?
on 2016-12-13 09:41
on 2016-12-14 01:24
I believe you need to both include & extend B for this to work. Here is an example: =========================== module B BC = 4711 def g puts 'works' end def self.extended(base) base.send(:include, self) end end module I extend self extend B def f g puts BC end end I.f =========================== Explanation: When you use 'extend' everything is dumped into I's singleton class, and the singleton class is not part of the constant lookup path. Notice that this will add an extra 'g' instance method to I's public interface. If that's a problem you could try separating the constants & the methods like this: =========================== module B module Constants BC = 4711 end include Constants def g puts 'works' end def self.extended(base) base.send(:include, Constants) end end =========================== I hope that helps :) - Jesus Castello, blackbytes.info
on 2016-12-14 12:32
I never had considered doing include AND extend together. The complexity of the solution makes me wonder, whether what I want to achieve is really still in "Ruby spirit". Maybe my thinking was influenced too much by other languages (C++ namespaces for instance). Am I the (nearly) only one who wants to use modules in this way? In any case: Thanks a lot! Your suggestions helps indeed.