How to share variables across my .rb files?
Constants (which include modules and classes) are added to the shared global environment:
phrogz$ cat constants1.rb
TEST_VARIABLE = "test"
phrogz$ cat constants2.rb
require_relative 'constants1'
p TEST_VARIABLE
phrogz$ ruby constants2.rb
"test"Instance variables declared in main are all part of the same
main
:phrogz$ cat instance1.rb
@test_variable = "test"
phrogz$ cat instance2.rb
require_relative 'instance1'
p @test_variable
phrogz$ ruby instance2.rb
"test"Global variables are also all part of the same environment (tested in 1.8.6, 1.8.7, and 1.9.2):
phrogz$ cat global1.rb
$test_variable = "test"
phrogz$ cat global2.rb
require_relative 'global1'
p $test_variable, RUBY_DESCRIPTION
phrogz$ ruby global2.rb
"test"
"ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.7.0]"
Accessing a variable declared in another rb file
The best way to export data from one file and make use of it in another is either a class or a module.
An example is:
# price.rb
module InstancePrices
PRICES = {
'us-east-1' => {'t1.micro' => 0.02, ... },
...
}
end
In another file you can require
this. Using load
is incorrect.
require 'price'
InstancePrices::PRICES['us-east-1']
You can even shorten this by using include
:
require 'price'
include InstancePrices
PRICES['us-east-1']
What you've done is a bit difficult to use, though. A proper object-oriented design would encapsulate this data within some kind of class and then provide an interface to that. Exposing your data directly is counter to those principles.
For instance, you'd want a method InstancePrices.price_for('t1.micro', 'us-east-1')
that would return the proper pricing. By separating the internal structure used to store the data from the interface you avoid creating huge dependencies within your application.
How can I access a variable defined in a Ruby file I required in IRB?
While it is true that you cannot access local variables defined in required files, you can access constants, and you can access anything stored in an object that you have access to in both contexts. So, there are a few ways to share information, depending on your goals.
The most common solution is probably to define a module and put your shared value in there. Since modules are constants, you'll be able to access it in the requiring context.
# in welcome.rb
module Messages
WELCOME = "hi there"
end
# in irb
puts Messages::WELCOME # prints out "hi there"
You could also put the value inside a class, to much the same effect. Alternatively, you could just define it as a constant in the file. Since the default context is an object of class Object, referred to as main, you could also define a method, instance variable, or class variable on main. All of these approaches end up being essentially different ways of making "global variables," more or less, and may not be optimal for most purposes. On the other hand, for small projects with very well defined scopes, they may be fine.
# in welcome.rb
WELCOME = "hi constant"
@welcome = "hi instance var"
@@welcome = "hi class var"
def welcome
"hi method"
end
# in irb
# These all print out what you would expect.
puts WELCOME
puts @welcome
puts @@welcome
puts welcome
accessing variables in loaded source while in irb
like this:
def my_array
[1, 2, 3, 4, 5]
end
How do I share object from main file to supporting file in ruby?
Remember that variables are strictly local unless you expressly pass them in. This means s
only exists in the main
context. You can fix this by passing it in:
reply(s, line)
And on the receiving side:
def reply(s, input)
# ...
end
I'd strongly encourage you to try and indent things consistently here, this code is really out of sorts, and avoid using global variables like $connected
. Using a simple self-contained class you could clean up this code considerably.
Also, don't add .rb
extensions when calling require
. It's implied.
Can two different .rb files access the same variable?
I think something like this is what you're looking for:
#web.rb
require './functions'
print_value("apple")
and
#rufus.rb
require './functions'
print_value("not apple")
and
#functions.rb
def print_value(value)
puts value
end
Calling web.rb returns the string Apple.
Declaring variables in .rb file result unwanted output
The two pieces of code are completely different. The first uses variables, the second uses methods.
Variables are defined like this:
name_of_var = initialization_expression
Methods are defined like this:
def name_of_method(parameter_one, parameter_two)
body_expression
end
I don't know if the bug is on the way I declare
statement
orenvironment
Yes.
This is what happens:
def statement
Assign.new(:x, Add.new(Variable.new(:x), Number.new(1)))
end
def environment
{ x: Number.new(2) }
end
Here you define two methods, statement
and environment
. What they do is actually irrelevant because you never call them.
statement, environment = statement.reduce(environment)
Here, you declare two variables, statement
and environment
. You initialize them by calling reduce
on the contents of the variable statement
(which is nil
, because statement
hasn't been initialized yet (we are just in the process of initializing it, after all) and un-iintialized variables evaluate to nil
in Ruby) passing as an argument the contents of the variable environment
(which is also nil
for the same reason).
You never call the methods you defined, because they are being shadowed by the two variables you created with the same names.
how could I solve it?
You already did: the first piece of code works.
Related Topics
How to Return Something Early from a Block
How to Measure the Size of a Ruby Object
What Does Post.All.Map(&:Id) Mean
Ruby/Rails - .Each Iterator Is Printing Entire Array at the End of the Loop
Rails: Copying Attributes from an Object to Another Using the "Attributes" Method
How to Get My MAChine's Ip Address from Ruby Without Leveraging from Other Ip Address
In Ruby, How to Output JSON from Hash and Give It Line Breaks and Tabs
Rendering a Partial from a Controller in Rails
Cannot Execute "Rails Console" Due to an Error with Readline
Ruby Invalid Byte Sequence in Utf-8
How to Spawn a Child Process in Ruby
Error Installing Debugger: Failed to Build Gem Native Extension with Ruby-1.9.3-P362