class Rscons::VarSet

This class represents a collection of variables which supports efficient deep cloning.

Public Class Methods

new(vars = {}) click to toggle source

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

[](key) click to toggle source

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
[]=(key, val) click to toggle source

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
append(values) click to toggle source

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
clone(other = {})
Alias for: merge
expand_varref(varref, lambda_args) click to toggle source

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
get_var(key) click to toggle source

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
include?(key) click to toggle source

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
inspect() click to toggle source

Return a String representing the VarSet.

@return [String] Representation of the VarSet.

# File lib/rscons/varset.rb, line 188
def inspect
  to_h.inspect
end
merge(other = {}) click to toggle source

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
Also aliased as: clone
to_h() click to toggle source

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
values_at(*keys) click to toggle source

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

coa!() click to toggle source

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
deep_dup(obj) click to toggle source

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