Forum: Ruby Mixing in a constant from another module

0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2016-12-13 09:41
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?
C2d1339038b5fec16b5b15878f648d96?d=identicon&s=25 Jesus Castello (jesus_castello)
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
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
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.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.