Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing a variable declared in another rb file

Tags:

ruby

this is a begginer question about including .rb files.

I would like to have access to an array declared in another rb file. My main program goes like this :

#!/usr/bin/env ruby
load 'price.rb'
[...]
max_price = price[az][type] * 2
[...]

and here is the price.rb :

price = {'us-east-1' => {'t1.micro' => 0.02, 'm1.small' => 0.08, 'c1.medium' => 0.165, 'm1.large' => 0.320 },
'us-west-1' => {'t1.micro' => 0.02, 'm1.small' => 0.08, 'c1.medium' => 0.165, 'm1.large' => 0.320 },
'eu-west-1' => {'t1.micro' => 0.02, 'm1.small' => 0.085, 'c1.medium' => 0.186, 'm1.large' => 0.340 }
}

When I run the main script I get this error :

Error: undefined local variable or method `price' for main:Object

What do you think ?

like image 882
PapelPincel Avatar asked Aug 23 '12 13:08

PapelPincel


4 Answers

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.

like image 97
tadman Avatar answered Nov 15 '22 16:11

tadman


Declaring the variable inside a tiny and simple class would be the cleaner solution imho.

like image 40
akluth Avatar answered Nov 15 '22 16:11

akluth


A quote from a Ruby forum:

Keep in mind that using load keeps local variables local to their scope within the file.

Which means that you can use the price variable only if it is not local; an example with instance variable:

@price = {'us-east-1' => {'t1.micro' => 0.02, 'm1.small' => 0.08, 'c1.medium' => 0.165, 'm1.large' => 0.320 }, 'us-west-1' => {'t1.micro' => 0.02, 'm1.small' => 0.08, 'c1.medium' => 0.165, 'm1.large' => 0.320 }, 'eu-west-1' => {'t1.micro' => 0.02, 'm1.small' => 0.085, 'c1.medium' => 0.186, 'm1.large' => 0.340 } }
like image 41
Vidul Avatar answered Nov 15 '22 14:11

Vidul


You cannot access variable from another file, but you can access function from another file:

file1.rb

# in case of script you may use 'global' variables (with $) 
# as they have scope visibility to this whole file 
$foo = 'bar'

def getFoo
    $foo
end

file2.rb

require_relative 'file1.rb'
foo = getFoo
# ...
like image 3
msangel Avatar answered Nov 15 '22 14:11

msangel