Forum: Ruby Enumerating constants in anonymous modules

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Daa9d36e8d07746041fb5650aba957b1?d=identicon&s=25 Xavier Shay (xaviershay2)
on 2008-10-09 17:24
How can I enumerate all the constants inside the module in the second
example?
Notice that #constants array is empty

For bonus points, which is the "correct" eval method to use to define a
class inside the module (they all seem to work)

Cheers,
Xavier

module Foo
  class A
  end
end

puts Foo.constants.inspect # => ["A"]

[:module_eval, :instance_eval, :class_eval].each do |method|
  m = Module.new
  m.send(method) do
    class B
    end
  end
  puts m.constants.inspect      # => [] (I would expect ['B'])
  puts m.const_get('B').inspect # => B
end
F53b05cdbdf561cfe141f69b421244f3?d=identicon&s=25 David A. Black (Guest)
on 2008-10-09 17:57
(Received via mailing list)
Hi --

On Fri, 10 Oct 2008, Xavier Shay wrote:

> How can I enumerate all the constants inside the module in the second
> example?
> Notice that #constants array is empty

See comments in code, below.

> For bonus points, which is the "correct" eval method to use to define a
> class inside the module (they all seem to work)

module_eval and class_eval are synonyms for each other. I'd use
module_eval over instance_eval, unless you specifically need instance
methods to be singleton methods on the module object (which is
unlikely, and can be achieved by other means under module_eval).

>    class B
The constant B is resolved in the usual "semi-static", eager way,
which means it does not belong to the new module: it's actually being
defined at the top level.

>    end
>  end
>  puts m.constants.inspect      # => [] (I would expect ['B'])
>  puts m.const_get('B').inspect # => B
> end

Try this:

   m = Module.new
   m.module_eval do
     class self::B    # forces Ruby to wait to bind the constant
     end
   end
   puts m.constants.inspect         #   ["B"]
   puts m.const_get('B').inspect    #   #<Module:0x220164>::B


David
Daa9d36e8d07746041fb5650aba957b1?d=identicon&s=25 Xavier Shay (xaviershay2)
on 2008-10-09 18:05
David A. Black wrote:
> Hi --
>
> On Fri, 10 Oct 2008, Xavier Shay wrote:
>
>> How can I enumerate all the constants inside the module in the second
>> example?
>> Notice that #constants array is empty
>
> See comments in code, below.
>
>> For bonus points, which is the "correct" eval method to use to define a
>> class inside the module (they all seem to work)
>
> module_eval and class_eval are synonyms for each other. I'd use
> module_eval over instance_eval, unless you specifically need instance
> methods to be singleton methods on the module object (which is
> unlikely, and can be achieved by other means under module_eval).

I'm not really sure what I need, I'll do some more reading and come back
if I have any further questions. Using module_eval for now.

> Try this:
>
>    m = Module.new
>    m.module_eval do
>      class self::B    # forces Ruby to wait to bind the constant
>      end
>    end
>    puts m.constants.inspect         #   ["B"]
>    puts m.const_get('B').inspect    #   #<Module:0x220164>::B

This does what I want, cheers
This topic is locked and can not be replied to.