David Moles David Moles - 7 months ago 14
Ruby Question

Iterate over only public Ruby constants

Since Ruby 2.0 or so, it's been possible to make a constant private using

, resulting in an error if the constant is used directly outside the declaring module.

However,
constants
and
const_defined?
still return private constants, and
const_get
allows access to them. Is there a way to programmatically identify private constants and filter them out at run time?

(Note: What does Module.private_constant do? Is there a way to list only private constants? and its answer don't specifically address this case, but rather the reverse (how to list only private constants).)




Update: It looks as though in Ruby 1.9 and 2.0,
constants
did include only public constants. As of 2.1, the no-arg
constants
still includes only public constants, but setting
inherit
to
false
with
constants(false)
(i.e., list only constants defined in this module, not in its ancestor modules) has the side effect of exposing the private constants.

Answer

You can identify constants by next way:

class A
  C = "value"
  private_constant :C
  C2 = "value2"
end

A.constants #public constants
#=> [:C2]
A.constants(false) #public & private constants
#=> [:C, :C2]
A.constants(false) - A.constants #private constants
#=> [:C]
Comments