never_had_a_name
never_had_a_name

Reputation: 93196

Store configuration in a file like Rails

I want to accomplish the same thing Rails has done, to store configurations in rb files that are read by the application:

# routes.rb
MyApp::Application.routes.draw do |map|
  root :to => 'firstpage#index'
  resources :posts

In rails the methods "root" and "resources" are not defined in the object "main" scope.

That means that these methods are defined in either a module or a class. But how did they require the routes.rb file and used these methods from a class/module.

Because if I use "require" then these methods will be executed in the "main" scope, no matter where i run "require".

So how could you like Rails read this configuration file and run the methods defined in a class/module?

Thanks

Upvotes: 3

Views: 174

Answers (3)

Adrian
Adrian

Reputation: 15171

The answer to your edit is that rails did not use yield or Proc#call in the draw method. It probably used instance_eval or class_eval.

(Edit) For example, here is how the draw method could possibly be defined:

def draw(&blk)
  class << context = Object.new
    def root(p1, p2)
      # ...
    end
    def resources(p1, p2)
      # ...
    end
  end
  context.instance_eval(&blk)
end

Then, you could use it like this:

draw do
  root 2, 3
  resources 4, 5
end

Upvotes: 1

Rein Henrichs
Rein Henrichs

Reputation: 15605

There is no way to effectively do this. require requires the contents files, period. It does not offer any other behavior. The eval solution is inferior to actually writing your Ruby files correctly so they contain their appropriate namespace information. If you want to include behavior in multiple classes, use modules.

Upvotes: 3

Marcel Jackwerth
Marcel Jackwerth

Reputation: 54762

Not really what I would consider as benign code, but that's how you could do it:

class A
  eval(File.read('yourfile.rb'))
end

Upvotes: 2

Related Questions