Class: Soroban::Cell

Inherits:
Object
  • Object
show all
Defined in:
lib/soroban/cell.rb

Overview

Represents a single cell in a sheet. This class is used internally, and isn't exposed to the caller. The cell stores the original string representation of its contents, and the executable Ruby version of same, as generated via a rewrite grammar. Cells also store their dependencies.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context) ⇒ Cell

Cells are initialised with a binding to allow formulas to be executed within the context of the sheet which owns the cell.



20
21
22
23
24
25
26
27
28
# File 'lib/soroban/cell.rb', line 20

def initialize(context)
  @dependencies = Set.new
  @excel = nil
  @ruby = nil
  @_binding = context
  @_touched = false
  @_value = nil
  @_tree = nil
end

Instance Attribute Details

#dependenciesObject (readonly)

Returns the value of attribute dependencies



16
17
18
# File 'lib/soroban/cell.rb', line 16

def dependencies
  @dependencies
end

#excelObject (readonly)

Returns the value of attribute excel



16
17
18
# File 'lib/soroban/cell.rb', line 16

def excel
  @excel
end

#rubyObject (readonly)

Returns the value of attribute ruby



16
17
18
# File 'lib/soroban/cell.rb', line 16

def ruby
  @ruby
end

Instance Method Details

#add_dependencies(labels) ⇒ Object

Used by the parser to add information about which cells the value of this particular cell is dependent on. May pass in a single cell label or a collection of cells labels. The dependencies are stored as a Set, so the best way of adding the labels is to ensure they're converted to an enumerable (with [labels].flatten), and then to assign the union of the Set with that enumerable (with |=)



74
75
76
# File 'lib/soroban/cell.rb', line 74

def add_dependencies(labels)
  @dependencies |= [labels].flatten unless labels.nil?
end

#clearObject

Clear the cached value of a cell to force it to be recalculated. This should be unnecessary to call explicitly.



50
51
52
# File 'lib/soroban/cell.rb', line 50

def clear
  @_value = nil
end

#getObject

Compute the value of the cell by evaluating the #ruby version of its contents within the context of the owning sheet. Will raise a Soroban::RecursionError if recursion is detected.



57
58
59
60
61
62
63
64
65
66
# File 'lib/soroban/cell.rb', line 57

def get
  raise Soroban::RecursionError, "Loop detected when evaluating '#{@excel}'" if @_touched
  @_touched = true
  @_value ||= eval(@ruby, @_binding)
  @_value
rescue TypeError, RangeError, ZeroDivisionError
  nil
ensure
  @_touched = false
end

#set(contents) ⇒ Object

Set the contents of a cell, and store the executable Ruby version. A Soroban::ParseError will be raised if an attempt is made to assign a value that isn't recognised by the Excel parser (although in most cases this should be treated as if you've passed in a string value). Note that assigning to the cell may cause its computed value to change; call #get to retrieve that. Note also that #set calls #clear internally to force recomputation of this value on the next #get call.



37
38
39
40
41
42
43
44
45
46
# File 'lib/soroban/cell.rb', line 37

def set(contents)
  contents = contents.to_s
  contents = "'#{contents}'" if Soroban::Helpers.unknown?(contents)
  clear
  @excel = contents
  @_tree = Soroban::Parser.instance.parse(@excel)
  raise Soroban::ParseError, Soroban::Parser.instance.failure_reason if @_tree.nil?
  @dependencies.clear
  @ruby = @_tree.to_ruby(self)
end