views:

54

answers:

2

How this simple task can be done in Ruby?
I have some simple config file

=== config.rb
config = { 'var' => 'val' }

I want to load config file from some method, defined in main.rb file so that the local variables from config.rb became local vars of that method.
Something like this:

=== main.rb
Class App
    def loader
        load('config.rb') # or smth like that
        p config['var']   # => "val"
    end
end

I know that i can use global vars in config.rb and then undefine them when done, but i hope there's a ruby way )

+3  A: 

You certainly could hack out a solution using eval and File.read, but the fact this is hard should give you a signal that this is not a ruby-like way to solve the problem you have. Two alternative designs would be using yaml for your config api, or defining a simple dsl.

The YAML case is the easiest, you'd simply have something like this in main.rb:

Class App
  def loader
      config = YAML.load('config.yml')
      p config['var']   # => "val"
  end
end

and your config file would look like:

--- 
var: val
NZKoz
Yaml won't work: config.rb is just an example - there should be some proccessings - not just serialized data. Actually, I need a simple command "exec_file_as_it_was_typed_here(file)". btw, php can do this )
disfated
Also, dsl and especially eval are not variants. At least for now. I just want to keep things simple.
disfated
The short version is that ruby can't do this, the longer version is that you should be defining and executing a DSL rather than relying on a clever hack with scoping.
NZKoz
"php can do this" ... trying not to scream... there are untold numbers of websites on the internet that are proof that PHP can do that, and that cause the rest of us to curse the programmers who allowed it.
Greg
A: 

I do NOT recommend doing this except in a controlled environment.

Save a module to a file with a predetermined name that defines an initialize and run_it methods. For this example I used test.rb as the filename:

module Test
  @@classvar = 'Hello'
  def initialize
    @who = 'me'
  end

  def get_who
    @who
  end

  def run_it
    print "#{@@classvar} #{get_who()}"
  end
end

Then write a simple app to load and execute it:

require 'test'

class Foo
  include Test
end

END {
  Foo.new.run_it
}

# >> Hello me

Just because you can do something doesn't mean you should. I cannot think of a reason I'd do it in production and only show it here as a curiosity and proof-of-concept. Making this available to unknown people would be a good way to get your machine hacked because the code could do anything the owning account could do.

Greg
thanks for the approach, but as you can see yourself - this is more redundant solution than even 'php style'...
disfated
I'm not particularly enthusiastic about metaprogramming, but php is a hell for me. I thought that so powerful dynamic tool like ruby can do such a primitive task. Bad news. It can't.Thanks all for your attention!
disfated