Class: Liquidscript::ICR::Context

Inherits:
Object
  • Object
show all
Includes:
Representable
Defined in:
lib/liquidscript/icr/context.rb

Overview

Handles variables within blocks. Each variable will get a reference in each context. When retrieving the value of a variable, if the variable was not introduced in the scope, it will look to its parent for the value of the variable. When setting the value of a variable, a new variable is forcibly created.

Constant Summary collapse

DEFAULT_ALLOWED_VARIABLES =

The variables that are allowed to be used as a global scope, i.e. used in a ‘get` context without a previous `set`.

%w(
  window global exports console this arguments
  Infinity NaN undefined eval isFinite isNaN parseFloat
  parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent
  Object Function Boolean Error EvalError InternalError RangeError
  ReferenceError SyntaxError TypeError URIError Number Math
  Date String  RegExp Array Float32Array Float64Array Int16Array
  Int32Array Int8Array Uint16Array Uint32Array Uint8Array
  Uint8ClampedArray ArrayBuffer DataView JSON Intl
).map(&:intern).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Representable

#to_a!, #to_ary, #to_sexp, #to_yaml

Constructor Details

#initializeContext

Returns a new instance of Context.



32
33
34
35
# File 'lib/liquidscript/icr/context.rb', line 32

def initialize
  @variables = {}
  @undefined = []
end

Instance Attribute Details

#parentObject

Returns the value of attribute parent.



29
30
31
# File 'lib/liquidscript/icr/context.rb', line 29

def parent
  @parent
end

#variablesObject (readonly)

Returns the value of attribute variables.



30
31
32
# File 'lib/liquidscript/icr/context.rb', line 30

def variables
  @variables
end

Instance Method Details

#allowed_variablesObject



37
38
39
# File 'lib/liquidscript/icr/context.rb', line 37

def allowed_variables
  DEFAULT_ALLOWED_VARIABLES.dup
end

#class!Boolean

Sets this context to be associated with a class.

Returns:

  • (Boolean)

See Also:

  • Liquidscript::ICR::Context.{{#class?}


84
85
86
# File 'lib/liquidscript/icr/context.rb', line 84

def class!
  @class = true
end

#class?Boolean

If this context is associated with a class. The context will forward any errors until after the context is completely finalized.

Returns:

  • (Boolean)

See Also:

  • Liquidscript::ICR::Context.{{#class!}


77
78
79
# File 'lib/liquidscript/icr/context.rb', line 77

def class?
  @class
end

#delegateObject

Delegates a block, such that the contents don’t affect the current context.

Returns:

  • (Object)

    the value of the block



64
65
66
67
68
69
# File 'lib/liquidscript/icr/context.rb', line 64

def delegate
  old, @delegate = @delegate, true
  out = yield
  @delegate = old
  out
end

#delegate!Boolean

Sets whether or not the context will delegate setting variables to its parent.

Returns:

  • (Boolean)

See Also:

  • Liquidscript::ICR::Context.{{#delegate?}


56
57
58
# File 'lib/liquidscript/icr/context.rb', line 56

def delegate!
  @delegate = !delegate?
end

#delegate?Boolean

If the context delegates setting variables to its parents. This keeps this context from getting any variables set on it, and instead sets variables on the parent.

Returns:

  • (Boolean)

See Also:

  • Liquidscript::ICR::Context.{{#delegate!}


47
48
49
# File 'lib/liquidscript/icr/context.rb', line 47

def delegate?
  @delegate
end

#force_defined!Object

Check if there are any undefined variables, and if there are, raise the first one it sees.



189
190
191
# File 'lib/liquidscript/icr/context.rb', line 189

def force_defined!
  @undefined.each { |f| raise f[1] }
end

#get(name, options = {}) ⇒ Variable, Boolean

Retrieves a reference to a variable. If the local context doesn’t have a reference, then it will try a few things; first, it will check to see if that variable is one of our allowed variables; second, it will check if the parent has a reference; otherwise, it will add an undefined reference if this context is associated with a class.

Parameters:

  • name (Symbol)

    the variable to reference.

  • options (Hash) (defaults to: {})

    Extra options.

Options Hash (options):

  • :dry_run (Boolean)

    if this is a dry run. In that case, it won’t add an undefined reference.

Returns:

Raises:

See Also:

  • Liquidscript::ICR::Context.{{#parent}
  • Liquidscript::ICR::Context.{{#allowed_variables}
  • Liquidscript::ICR::Context.{{#add_undefined}
  • Liquidscript::ICR::Context.{{#variables}


108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/liquidscript/icr/context.rb', line 108

def get(name, options = {})
  variables.fetch(name) do
    case true
    # If the asking variable is an allowed variable, we'll
    # allow it, and just return a variable instance.
    when allowed_variables.include?(name)
      Variable.new(self, name, :allowed => true)
    # If we have a parent, we can ask the parent for the
    # variable.  This takes precedence over the class
    # so we can get a proper reference to the correct
    # variable.
    when !!parent
      parent_get(name, options)
    # If this context is associated with a class, and
    # we're not doing a dry run, then we'll add an
    # undefined.
    when @class && !options[:dry_run]
      add_undefined(name)
    # If we are doing a dry run, however, then just let
    # the caller know that it would have been successful.
    when @class && options[:dry_run]
      true
    # If none of those options fit, raise an error.
    else
      raise InvalidReferenceError.new(name)
    end
  end
end

#hiddenArray<Variable>

Retrieves all of the variables that are hidden in the current context.

Returns:

See Also:

  • Liquidscript::ICR::Context.{Variable{Variable#hidden?}


174
175
176
# File 'lib/liquidscript/icr/context.rb', line 174

def hidden
  variables.values.select(&:hidden?)
end

#parametersArray<Variable>

Retrieves all of the variables that are parameters in the current context.

Returns:

See Also:

  • Liquidscript::ICR::Context.{Variable{Variable#parameter?}


165
166
167
# File 'lib/liquidscript/icr/context.rb', line 165

def parameters
  variables.values.select(&:parameter?)
end

#set(name, options = {}) ⇒ Variable

If this context delegates, it delegates to the parent; otherwise, it will check if we have set this variable before. Otherwise, it will first reject any undefined variables that existed with the specific name, and then create a new variable with the given options.

Parameters:

  • name (Symbol)

    the name of the variable.

  • options (Hash) (defaults to: {})

    the options to pass to the new variable instance.

Returns:

See Also:

  • Liquidscript::ICR::Context.{{#variables}
  • Liquidscript::ICR::Context.{{#parent}
  • Liquidscript::ICR::Context.{{#delegate?}


150
151
152
153
154
155
156
157
158
# File 'lib/liquidscript/icr/context.rb', line 150

def set(name, options = {})
  return parent.set(name, options) if delegate?

  variables.fetch(name) do
    @undefined.reject! { |(n, _)| n == name }
    variables[name] = Variable.new(self, name,
      { :class => class? }.merge(options))
  end
end

#to_aArray<Symbol>

Returns the name of the variables in this context.

Returns:



181
182
183
# File 'lib/liquidscript/icr/context.rb', line 181

def to_a
  variables.keys
end