1

What I'm attempting to do in Ruby is the equivalent to PHP's include or require statement.

In PHP, when you include or require a file, any PHP code in the included file is executed and globally scoped variables can be used in the file that houses the include.

In Ruby, I have this code;

# include file snippet
config = {'base_url' => 'http://devtest.com/'}

# main file
Dir.foreach(BASE_ROOT_PATH + 'config') do |file|
  if !(file == '.' || file == '..')
    filepath = BASE_ROOT_PATH + 'config/' + file
    load filepath
  end
end

config.inspect

The problem I'm encountering is that when I run the main file, it always errors out with this error;

/home/skittles/devtest/bootstrap.rb:24:in `<top (required)>': undefined local variable or method `config' for main:Object (NameError)
    from <internal:lib/rubygems/custom_require>:29:in `require'
    from <internal:lib/rubygems/custom_require>:29:in `require'
    from index.rb:27:in `<main>'

I know that it's pulling in the file because it's not throwing any errors. I tried load & require, both with the same error. I tried config.inspect and puts config, still same error.

It's almost like the included file is not executing the code inside it. Is that what's going on or am I simply doing something wrong?

Thanks

Skittles
  • 2,866
  • 9
  • 31
  • 37
  • Can I ask what you are trying to accomplish? Loading all config files in the wrong sequence is what is causing this error. You typically would only load the 'environment.rb' file, and that would load everything else – PinnyM Feb 01 '12 at 14:58
  • OP doesn't say he's using Rails... – Chowlett Feb 01 '12 at 15:00
  • Possible duplicate of http://stackoverflow.com/questions/2699324/ruby-irb-requires-and-scope – Chowlett Feb 01 '12 at 15:04
  • I'm not using Rails. I am using Ruby. @PinnyM - I created a file that will contain config settings in it and wish to load that file along with any other files in that directory with the code you see in the main file. I then need to be able to access the vars read in from the included file. – Skittles Feb 01 '12 at 15:04
  • @Chowlett, good point. Just a coincidence that there's a 'config' directory – PinnyM Feb 01 '12 at 15:05
  • @ Chowlett - This is not even remotely similar to that link. Please don't be so quick to assume that I haven't done my searches and research first. – Skittles Feb 01 '12 at 15:06
  • @ Chowlett - The config directory is my own creation. Again, This is not Rails. In fact, it's preferred that Rails doesn't even come into this equation. This is strictly Ruby. – Skittles Feb 01 '12 at 15:07
  • So you're trying to use the config you've defined in that snippet from inside the files loaded via load/require ? – Frederick Cheung Feb 01 '12 at 15:10
  • @Frederick - Yes. I simply wish to be able to use the config variable in the main file after having been loaded or required. – Skittles Feb 01 '12 at 15:11
  • @Skittles - I never thought it was Rails. And I think that link is relevant; _you cannot access "local variables" defined in external files across a `require`_. You need a constant, instance variable or method. – Chowlett Feb 01 '12 at 15:12
  • @Chowlett - My understanding of "local variables" is that they are local to a given scope. If my config variable is not confined to a def or other form of block, then its scope should be global. Or is Ruby totally backwards in that respect? – Skittles Feb 01 '12 at 15:15
  • @Skittles: Local variables are local. That's why they are called local variables. If you want a global variable, use a global variable. I'm not sure why you think that the fact that local variables are local is "backwards". I, personally, would think the opposite: local variables being global would be *extremely* ass-backwards. – Jörg W Mittag Feb 01 '12 at 15:27
  • @Jörg - Obviously, you totally didn't read what I said properly. A local variable in any other language means that that variable is "local" to the blocks it was defined in. In PHP & Perl, if you define a variable outside of a function or if or for "block", then it's global to the entire script. So, in Ruby, defining a var in an open context as I did, would make that var global. – Skittles Feb 01 '12 at 15:42
  • @Skittles: I still don't get a) why you expect local variables to be global, and b) why you think local variables *not* being global is backwards? Local variables defined in a block body are local to that block, local variables defined in a method body are local to that method, local variables defined in a class body are local to that class, local variables defined in a module body are local to that module, local variables defined in a script body are local to that script. Global variables are global. Why should local variables be global? – Jörg W Mittag Feb 01 '12 at 16:21
  • You obviously understand what scope is. What's you're also obviously overlooking though is the fact that when you come to Ruby from languages like PHP & Perl, Ruby's definition of "global" is not the same. My question was related to getting clarity on that very thing. I don't object to your attempt to provide clarity, but I do object to your rather abrasive position with my obvious lack of understanding how Ruby handles such things versus PHP or Perl. You might want to consider being less abrasive to people. It makes for a nicer place for newbs to not feel flamed. Good day! – Skittles Feb 01 '12 at 17:04

1 Answers1

2

config isn't a globally scoped variable - it's a local variable and local variable scope does not stretch across a require or load.

If you did want a global variable then you need to call it $config - the prefix denotes whether a variable is local (no prefix), global ($) or an instance variable (@). A constant might also be appropriate.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • Thank you, Frederick! I was not aware that Ruby had a symbol that denotes something as global. I changed the config line so that the variable is now $config. I think that worked. At least now, when I use a puts $config.to_yaml, it actually shows me the value in the config var. – Skittles Feb 01 '12 at 15:24