Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

You use eval, but eval is evil eval is evil.

You use eval, but eval is evil.

You use eval, but eval is evil.

typo correction
Source Link
knut
  • 1.3k
  • 1
  • 10
  • 16
  • Module.const_set to define constants
  • Module.const_defined to check if a constant is defined
  • Module.getconst_get to navigate inside modules
  • Module.new to define new modules.

My solution (including a littelittle test):

  • Module.const_set to define constants
  • Module.const_defined to check if a constant is defined
  • Module.get to navigate inside modules
  • Module.new to define new modules.

My solution (including a litte test):

  • Module.const_set to define constants
  • Module.const_defined to check if a constant is defined
  • Module.const_get to navigate inside modules
  • Module.new to define new modules.

My solution (including a little test):

Source Link
knut
  • 1.3k
  • 1
  • 10
  • 16

You use eval, but eval is evil.

I tried a solution without eval. For this I used:

  • Module.const_set to define constants
  • Module.const_defined to check if a constant is defined
  • Module.get to navigate inside modules
  • Module.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 initial context.
  • (and sure: I renamed the method ;-) )
lang-rb

AltStyle によって変換されたページ (->オリジナル) /