I have a somewhat basic question: lets say that in my working directory
I have a file called my_vars.rb.
It contains:
x = 5.0
puts “your variable x is #{x}”
Now, I fire up irb in my command window, and type in
require “my_vars.rb”
Which outputs, as expected,
your variable x is 5.0
=> true
Now, I want to access that variable again, so I enter in:
puts x
and I get an error saying that x is undefined. It’s like it was
temporarily there in memory, but then once it was used, it got thrown
away! Does anyone know how to load in a file and keep using the
variables that were in said file?
I have a somewhat basic question: lets say that in my working directory
I have a file called my_vars.rb.
It contains:
x = 5.0
puts “your variable x is #{x}”
Now, I fire up irb in my command window, and type in
require “my_vars.rb”
Which outputs, as expected,
your variable x is 5.0
=> true
Now, I want to access that variable again, so I enter in:
puts x
and I get an error saying that x is undefined. It’s like it was
temporarily there in memory, but then once it was used, it got thrown
away! Does anyone know how to load in a file and keep using the
variables that were in said file?
Thanks!
You could define x as a global variable $x e.g.: #in my_vars.rb
$x = 5
puts “your variable x is #{$x}”
Using globals to allow locals to talk across files seems pretty shaky.
Why
do you need to be able to do this? Probably there is a better way.
Perhaps
put all that code into one file. Perhaps put it into a method, and have
it
return the variables of interest (you can conditionally invoke the
method if
the file is required vs if the file is the primary program by comparing
$0
to FILE)
require “my_vars.rb”
away! Does anyone know how to load in a file and keep using the
variables that were in said file?
Thanks!
There is a way around this, although I think that the “usual” solutions
(wrapping this data into a proper object or method) are much better.
All code in Ruby is evaluated inside the context of an object. In other
terms: self is always defined. Code outside of class statements, module
statements and some special statements that change the binding is
evaluated inside the toplevel object (called “main”). “main” is just a
normal object and we can thus set instance variables:
File: test.rb @b = 42
File: inc.rb
require “test”
puts @b #=> prints 42
Those instance variables can only be accessed in the toplevel context
and not in any other object or class.
I don’t think this is a good way to do it, but it is a nice way of
illustrating how far “everything is an object” is rooted into ruby.
require “my_vars.rb”
away! Does anyone know how to load in a file and keep using the
variables that were in said file?
Thanks!
The basic construct that you are discovering here is variable scope. It
is not that irb lost your variable or ever had it defined in memory. In
fact this problem has nothing to do with irb as the following
demonstrates:
wes:~> cat > a.rb << EOF
x = ‘Hi’
puts x
EOF
wes:~> cat > b.rb << EOF
require ‘a’
puts “in b #{x}”
EOF
wes:~> ruby a.rb
Hi
wes:~> ruby b.rb
Hi
b.rb:3: undefined local variable or method `x’ for main:Object
(NameError)
The variable is only available locally in the original script a.rb.
Tthe second script has no knowledge of this variable and it raises the
NameError exception. If you want the variable to be available to both
script define a global:
wes:~> cat a.rb
$x = ‘Hi’
puts $x
wes:~> cat b.rb
require ‘a’
puts “in b #{$x}”
wes:~> ruby b.rb
Hi
in b Hi