Class: RVM::Interpreter::Environment
- Inherits:
-
Object
- Object
- RVM::Interpreter::Environment
- Defined in:
- lib/rvm/environment.rb
Overview
The environment holds environmental variables like who executes the code, on what object it runs, what parameters where passed to the call and as well, and perhaps most importantly the local variables.
Some of the functions called will initialize new environments, as for example function calls.
Instance Method Summary collapse
-
#[](k) ⇒ Object
Returns a local variable with the given name.
-
#[]=(name, value) ⇒ Object
Sets a local variable witin the environment.
-
#data ⇒ Object
Allows raw access to the data, it should not be used unless somoene knows pretty exactly what they are doing.
-
#declare(name, value) ⇒ Object
Defines a varialbe in the current scope, priviose variables are not changed.
-
#def_function(name, body) ⇒ Object
This defines a function within the environment and lets you call it later on.
-
#function(name) ⇒ Object
Returns a function for the environment.
-
#initialize(init_data = {}, oldenv = nil) ⇒ Environment
constructor
This creates a new environment environment, it generates a new env default variables are set if not defined in
data
. -
#param(i) ⇒ Object
returns a parameter that was passed to the call.
- #path ⇒ Object
-
#read_var_val(name) ⇒ Object
This functin is closely related to
[]
with the difference that it returns the value and not the VariableStorage object.
Constructor Details
#initialize(init_data = {}, oldenv = nil) ⇒ Environment
This creates a new environment environment, it generates a new env default variables are set if not defined in data
.
If oldenv
is provided it will also fall back to see if not existing variables
init_data
is a hash that can be passed the following values:
- :locals
-
A hash with local variables mapped name => value
- :functions
-
A hash with functions for the scope.
- :evaldeepth
-
A fixnum that indicates how deep the evaluation is.
- :params
-
A array that holds local parameters for example for functions or blocks.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rvm/environment.rb', line 23 def initialize init_data = {}, oldenv=nil @data = { :locals => {}, #oldenv ? oldenv.data[:locals] : {}, :locals_swapped => true, # init_data.keys.include?(:locals), :functions => oldenv ? oldenv.data[:functions] : {}, :functions_swapped => init_data.keys.include?(:functions), :evaldeepth => 0, :params => oldenv ? oldenv.data[:params] : [], :params_swapped => init_data.keys.include?(:params) }.merge(init_data) @path = [] if oldenv.nil? # Make sure that all locals that are passed, are actually in a variable # storage. if init_data[:locals] # For easy access we get us a link to the locals locals = @data[:locals] # Now we itterate through them init_data[:locals].each do |k,v| #For every variable that isn't already in a storage if not v.is_a?(VariableStorage) # We put it in a storage to assure the environment is propper. locals[k] = VariableStorage.new(v) end end end # We store the priviouse environment to look upwards through the scopes # for priviouse defined variables, if no old environment was given we # set the priviose scope to an empty hash. @prev = oldenv || {} RVM::debug "data: #{data}\noldenv:#{oldenv}" if $DEBUG RVM::debug "Creating new environment with: #{@data.inspect} as child" + " of #{@prev}" if $DEBUG end |
Instance Method Details
#[](k) ⇒ Object
Returns a local variable with the given name.
If the current environment does not have any local variables with the given name it tries the privious environments.
This returns the VariableData
object NOT the value of the variable. Use read_var_val
if you want to read the value of a variable.
92 93 94 95 96 97 98 |
# File 'lib/rvm/environment.rb', line 92 def [] k r = @data[:locals][k] r = @prev[k] if not r and @data[:locals_swapped] RVM::debug "Getting variable #{k} (#{r})" if $DEBUG r end |
#[]=(name, value) ⇒ Object
Sets a local variable witin the environment.
If the variable exists in a ‘higher’ environment the value is changed.
If not it is newly created in the current environment and thus not visible in upper environments.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/rvm/environment.rb', line 106 def []= name, value RVM::debug "Setting variable #{name} to #{value}" if $DEBUG # First we try to get the variable storage of the variable requested. # This will work if it was defined in this or a priviouse scope. if storage = self[name] # If we found the storage we'll change it's value and not define it # again. storage.val = value else # If we didn't found a Variable storage, the variable wasn't defined # before so we make a new VariableStorage and save the variable in # it. declare name, value end value end |
#data ⇒ Object
Allows raw access to the data, it should not be used unless somoene knows pretty exactly what they are doing.
63 64 65 |
# File 'lib/rvm/environment.rb', line 63 def data @data end |
#declare(name, value) ⇒ Object
Defines a varialbe in the current scope, priviose variables are not changed. This is needed for local varialbe declarations that overwrite priviouse globals.
128 129 130 131 132 133 134 135 |
# File 'lib/rvm/environment.rb', line 128 def declare name, value #Now we need to make our own set of storage! if not @data[:locals_swapped] @data[:locals_swapped] = true @data[:locals] = {} end @data[:locals][name] = VariableStorage.new(value) end |
#def_function(name, body) ⇒ Object
This defines a function within the environment and lets you call it later on.
It expects the body to be a RVM::Classes::Block so it can be executed. The return value is the given block
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/rvm/environment.rb', line 157 def def_function name, body if not body.is_a?(RVM::Classes::Block) raise(ArgumentError, "Function definitions must be of block class.") end #Now we need to make our own set of storage! if not @data[:functions_swapped] @data[:functions_swapped] = true @data[:functions] = {} end @data[:functions][name] = body RVM::debug "Setting functon #{name} (#{body})" if $DEBUG body end |
#function(name) ⇒ Object
Returns a function for the environment. If the current environment does not hold a function with the requested name it checks through the entire tree if a function can be found in the outer scopes.
The result is to be execpted to be of the RVM::Classes::Block
class.
142 143 144 145 146 147 148 149 150 |
# File 'lib/rvm/environment.rb', line 142 def function name # Try to get the function in the local defintions. fun = @data[:functions][name] # if that fails and we have a previous environment check that fun = @prev.function(name) if fun.nil? and @data[:functions_swapped] and @prev.is_a? Environment RVM::debug "Getting functon #{name} (#{fun})" if $DEBUG # return what was found fun end |
#param(i) ⇒ Object
returns a parameter that was passed to the call. For function calls this is especially important, it beginns with 0.
If the current environment does not have the given paramenter it tries it’s ‘oldenv’ attrib to see if that had a object.
76 77 78 79 80 81 82 83 |
# File 'lib/rvm/environment.rb', line 76 def param i RVM::debug "Getting param #{i} (#{@data[:params][i]})" if $DEBUG if @data[:params_swapped] @data[:params][i] || @prev.param(i) else @data[:params][i] end end |
#path ⇒ Object
67 68 69 |
# File 'lib/rvm/environment.rb', line 67 def path @path || @pre.path end |
#read_var_val(name) ⇒ Object
This functin is closely related to []
with the difference that it returns the value and not the VariableStorage object. It is equivalent to [].val just that it also deals with nil ojects and and returns a RVM::Classes::Error if the requested variable wasn’t found.
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/rvm/environment.rb', line 178 def read_var_val name r = nil if (v = self[name]) r = v.val else raise "Variable #{name} is not defined." end RVM::debug "Getting variable value #{name} (#{r})" if $DEBUG r end |