I have a command line utility written in Ruby using GLI framework. I would like to have configuration for my command line utility in my home directory, using Ruby itself as DSL to handle it (similar to Gemfile or Rakefile).
I have in class ConfigData in folder lib/myapp. The class looks like following way:
class ConfigData
@@data = {}
class ConfigItem
def initialize
@data = {}
end
def missing_method(name, *args)
@data[name] = args[0]
end
end
def self.add(section)
item = ConfigItem.new()
yield item
@@data[section]=item
end
end
Now, what I would like to have, is the config file, preferrably with name Myappfile, in current working folder, with the following content
add('section1') do |i|
i.param1 'Some data'
i.param2 'More data'
end
When this code was included between class and end of ConfigData, it worked fine. But now I would like to have it placed in the working folder, where I start the application.
I tried require(‘./Myappfile’) between class and end of ConfigData, but it doesn’t work for me. I tried to read the source codes of rake, but it is not very much clear to me.
Any hint how this can be solved?
To evaluate code within the context of an instance, which is what you want to do, you need the
instance_eval()method. Never, ever, use normal eval. Ever. Anyway, here’s how you’d load your fingi file and get the data:That simple. After you’ve loaded the object in that way, you can access values of the object.
WARNING: This is not very secure. This is actually a gaping security hole. Here’s the secure version:
This executes the external code in a (sort of) sandbox, so that it can’t do anything dastardly.
Also, why don’t you just use a YAML config? Unless configuration needs to run code like
pwdor access RUBY_VERSION, YAML is much simpler and more secure, in addition to being more failproof.