metaprogramming/constant_lookup_no_parens.rb
tests/_examples/metaprogramming/constant_lookup_no_parens.rb in the metorex repository.
# Where a constant is found: the scopes a method was written in, then the
# ancestors of the innermost one, then Object and the modules it includes.
# A private constant is read only without its scope written out.
# Written with as few parentheses as Ruby allows.
module Shared
RETRIES = 3
end
include Shared
module Settings
def self.retries
RETRIES
end
end
p Settings.retries
p ::RETRIES
class Base
LIMIT = :from_base
end
Object::LIMIT = :from_object
class Derived < Base
def self.limit
LIMIT
end
end
p Derived.limit
class Lenient
def self.const_missing(name)
:"missing_#{name}"
end
def self.lookup
UNDEFINED_HERE
end
end
p Lenient.lookup
anonymous = Module.new do
def self.name
nil
end
def self.inspect
"#<Settings module>"
end
end
begin
anonymous::ABSENT
rescue NameError => error
p error.message
end
class Vault
SECRET = :hidden
private_constant :SECRET
def self.reveal
SECRET
end
def self.known
defined?(SECRET)
end
end
p Vault.reveal
p Vault.known
p defined?(Vault::SECRET)
begin
Vault::SECRET
rescue NameError => error
p [error.message, error.name, error.receiver]
end
class Vault
class Inner
end
private_constant :Inner
end
begin
eval "class Vault::Inner; end"
rescue NameError => error
p error.message
end
begin
eval "def assigns\n LIMIT = 1\nend"
rescue SyntaxError => error
p error.message.include?("dynamic constant assignment")
end
class Object
HIDDEN_TOP = :top
private_constant :HIDDEN_TOP
end
p HIDDEN_TOP
begin
::HIDDEN_TOP
rescue NameError
p HIDDEN_TOP
end
Output:
3
3
:from_base
:missing_UNDEFINED_HERE
"uninitialized constant #<Settings module>::ABSENT"
:hidden
"constant"
nil
["private constant Vault::SECRET referenced", :SECRET, Vault]
"private constant Vault::Inner referenced"
true
:top
:top