You use eval, but eval is evil eval is evil.
You use eval, but eval is evil.
You use eval, but eval is evil.
Module.const_set
to define constantsModule.const_defined
to check if a constant is definedModule.getconst_get
to navigate inside modulesModule.new
to define new modules.
My solution (including a littelittle test):
Module.const_set
to define constantsModule.const_defined
to check if a constant is definedModule.get
to navigate inside modulesModule.new
to define new modules.
My solution (including a litte test):
Module.const_set
to define constantsModule.const_defined
to check if a constant is definedModule.const_get
to navigate inside modulesModule.new
to define new modules.
My solution (including a little test):
You use eval, but eval is evil.
I tried a solution without eval. For this I used:
Module.const_set
to define constantsModule.const_defined
to check if a constant is definedModule.get
to navigate inside modulesModule.new
to define new modules.
My solution (including a litte test):
def def_constants!(hash, context)
#context should be a module. If not, then get (or build) it.
if context.is_a? String
lcontext = Object
context.split('::').each{ |module_name|
lcontext.const_set(module_name, Module.new) unless lcontext.const_defined?(module_name)
lcontext = lcontext.const_get(module_name)
}
context = lcontext
end
raise ArgumentError unless context.is_a?(Module)
hash.each do |key, value|
case value
when Hash
module_name = key.upcase #fixme -- convert_string_to_camel_case(key)
def_constants!( hash[key], [context.name, module_name].join('::'))
when /::/ # explicitly build out this module (since it doesn't exist) so that we can talk about it
context.const_set(key.upcase, Module.new)
lmod = context.const_get(key.upcase)
value.split('::').each{ |module_name|
lmod = lmod.const_set(module_name, Module.new )
}
else
# define the given constant
context.const_set(key.upcase, value)
end
end #hash
end
module AA #define a start
end
require 'yaml'
def_constants!(YAML.load(DATA), AA)
p AA.constants
p AA::KEY
p AA::SAMPLE_MODULE::SOME_KEY
p AA::KEY_SHOULD_BE_MODULE
p AA::KEY_SHOULD_BE_MODULE::I
p AA::KEY_SHOULD_BE_MODULE::I.constants
p AA::KEY_SHOULD_BE_MODULE::I::Am
p AA::KEY_SHOULD_BE_MODULE::I::Am::A
p AA::KEY_SHOULD_BE_MODULE::I::Am::A::Module
__END__
key: value
numeric_data: 3.221
sample_module:
some_key: another value
key_should_be_module: I::Am::A::Module
I haven't tested it for each usecase. I expect problems, when you try to define modules, where you have already constants with the same name.
Some changes, to use it in your code:
- I skipped convert_string_to_camel_case(key) and replaced it with
upcase
- Your
@project_name
is my initialcontext
. - (and sure: I renamed the method ;-) )