class Rscons::VarSet
This class represents a collection of variables which supports efficient deep cloning.
Public Class Methods
Create a VarSet
.
@param vars [Hash] Optional initial variables.
# File lib/rscons/varset.rb, line 8 def initialize(vars = {}) @my_vars = {} @coa_vars = [] append(vars) end
Public Instance Methods
Access the value of a variable.
@param key [String, Symbol]
The variable name.
@return [Object]
The variable's value.
# File lib/rscons/varset.rb, line 21 def [](key) if @my_vars.include?(key) @my_vars[key] else @coa_vars.each do |coa_vars| if coa_vars.include?(key) @my_vars[key] = deep_dup(coa_vars[key]) return @my_vars[key] end end nil end end
Assign a value to a variable.
@param key [String, Symbol]
The variable name.
@param val [Object]
The value to set.
# File lib/rscons/varset.rb, line 67 def []=(key, val) @my_vars[key] = val end
Add or overwrite a set of variables.
@param values [VarSet, Hash] New set of variables.
@return [VarSet] Returns self.
# File lib/rscons/varset.rb, line 91 def append(values) coa! if values.is_a?(VarSet) values.send(:coa!) @coa_vars = values.instance_variable_get(:@coa_vars) + @coa_vars else @my_vars = deep_dup(values) end self end
Replace “$!{var}” variable references in varref with the expanded variables' values, recursively.
@param varref [nil, String, Array, Proc, Symbol, TrueClass, FalseClass]
Value containing references to variables.
@param lambda_args [Array]
Arguments to pass to any lambda variable values to be expanded.
@return [nil, String, Array, Symbol, TrueClass, FalseClass]
Expanded value with "$!{var}" variable references replaced.
# File lib/rscons/varset.rb, line 125 def expand_varref(varref, lambda_args) case varref when String if varref =~ /^(.*)\$\{([^}]+)\}(.*)$/ prefix, varname, suffix = $1, $2, $3 prefix = expand_varref(prefix, lambda_args) unless prefix.empty? varval = expand_varref(get_var(varname), lambda_args) # suffix needs no expansion since the regex matches the last occurence case varval when Array if prefix.is_a?(Array) varval.map {|vv| prefix.map {|p| "#{p}#{vv}#{suffix}"}}.flatten else varval.map {|vv| "#{prefix}#{vv}#{suffix}"} end when String, Symbol, true, false, nil if prefix.is_a?(Array) prefix.map {|p| "#{p}#{varval}#{suffix}"} else "#{prefix}#{varval}#{suffix}" end else raise "Unknown construction variable type: #{varval.class} (from #{varname.inspect} => #{get_var(varname).inspect})" end else varref end when Array varref.map do |ent| expand_varref(ent, lambda_args) end.flatten when Symbol, true, false, nil varref when Proc expand_varref(varref[*lambda_args], lambda_args) else raise "Unknown construction variable type: #{varref.class} (#{varref.inspect})" end end
Access the value of a variable.
This method is similar to []
but does not make a copy-on-access copy of the variable accessed. This means that the returned value is NOT safe to be modified by the caller. Thus the caller must guarantee that it does not modify the returned value.
@param key [String, Symbol]
The variable name.
@return [Object]
The variable's value.
# File lib/rscons/varset.rb, line 47 def get_var(key) if @my_vars.include?(key) @my_vars[key] else @coa_vars.each do |coa_vars| if coa_vars.include?(key) return coa_vars[key] end end nil end end
Check if the VarSet
contains a variable.
@param key [String, Symbol] The variable name.
@return [Boolean] Whether the VarSet
contains the variable.
# File lib/rscons/varset.rb, line 76 def include?(key) if @my_vars.include?(key) true else @coa_vars.find do |coa_vars| coa_vars.include?(key) end end end
Create a new VarSet
object based on the first merged with other.
@param other [VarSet, Hash] Other variables to add or overwrite.
@return [VarSet] The newly created VarSet
.
# File lib/rscons/varset.rb, line 107 def merge(other = {}) coa! varset = self.class.new varset.instance_variable_set(:@coa_vars, @coa_vars.dup) varset.append(other) end
Return a Hash containing all variables in the VarSet
.
@since 1.8.0
This method is not terribly efficient. It is intended to be used only by debugging code to dump out a VarSet's variables.
@return [Hash] All variables in the VarSet
.
# File lib/rscons/varset.rb, line 173 def to_h result = deep_dup(@my_vars) @coa_vars.reduce(result) do |result, coa_vars| coa_vars.each_pair do |key, value| unless result.include?(key) result[key] = deep_dup(value) end end result end end
Return an array containing the values associated with the given keys.
@param keys [Array<String, Symbol>]
Keys to look up in the VarSet.
@return [Array]
An array containing the values associated with the given keys.
# File lib/rscons/varset.rb, line 199 def values_at(*keys) keys.map do |key| self[key] end end
Private Instance Methods
Move all VarSet
variables into the copy-on-access list.
@return [void]
# File lib/rscons/varset.rb, line 210 def coa! unless @my_vars.empty? @coa_vars.unshift(@my_vars) @my_vars = {} end end
Create a deep copy of an object.
Only objects which are of type String, Array, or Hash are deep copied. Any other object just has its referenced copied.
@param obj [Object] Object to deep copy.
@return [Object] Deep copied value.
# File lib/rscons/varset.rb, line 225 def deep_dup(obj) case obj when String obj.dup when Array obj.map { |v| deep_dup(v) } when Hash obj.reduce({}) do |result, (k, v)| result[k] = deep_dup(v) result end else obj end end