class Soroban::Sheet
A container for cells.
Attributes
bindings[R]
Public Class Methods
new()
click to toggle source
Creates a new sheet.
# File lib/soroban/sheet.rb, line 13 def initialize @cells = {} @bindings = {} end
Public Instance Methods
bind(name, label)
click to toggle source
Bind one or more named variables to a cell.
# File lib/soroban/sheet.rb, line 55 def bind(name, label) unless @cells.keys.include?(label.to_sym) raise Soroban::UndefinedError, "Cannot bind '#{name}' to non-existent cell '#{label}'" end _bind(name, label) end
cells()
click to toggle source
Return a hash of `label => contents` for each cell in the sheet.
# File lib/soroban/sheet.rb, line 68 def cells Hash[@cells.keys.map { |label| label.to_s }.zip( @cells.keys.map { |label| eval("@#{label}.excel") } )] end
get(label_or_name)
click to toggle source
Retrieve the contents of a cell.
# File lib/soroban/sheet.rb, line 50 def get(label_or_name) _get(label_or_name, eval("@#{label_or_name}", binding)) end
method_missing(method, *args, &block)
click to toggle source
Used for calling dynamically defined functions, and for creating new cells (via `label=`).
Calls superclass method
# File lib/soroban/sheet.rb, line 20 def method_missing(method, *args, &block) if match = /^func_(.*)$/i.match(method.to_s) return Soroban::call(self, match[1], *args) elsif match = /^([a-z][\w]*)=$/i.match(method.to_s) return _add(match[1], args[0]) end super end
missing()
click to toggle source
Return a list of referenced but undefined cells.
# File lib/soroban/sheet.rb, line 73 def missing @cells.values.map.flatten.uniq - @cells.keys end
set(label_or_range, contents)
click to toggle source
Set the contents of one or more cells or ranges.
# File lib/soroban/sheet.rb, line 30 def set(label_or_range, contents) unless range = Soroban::getRange(label_or_range) return _add(label_or_range, contents) end fc, fr, tc, tr = range if fc == tc || fr == tr raise ArgumentError, "Expecting an array when setting #{label_or_range}" unless contents.kind_of? Array cc, cr = fc, fr contents.each do |item| set("#{cc}#{cr}", item) cc.next! if fr == tr cr.next! if fc == tc end raise Soroban::RangeError, "Supplied array doesn't match range length" if cc != tc && cr != tr else raise ArgumentError, "Can only set cells or 1-dimensional ranges of cells" end end
walk(range)
click to toggle source
Visit each cell in the supplied range, yielding its value.
# File lib/soroban/sheet.rb, line 63 def walk(range) Walker.new(range, binding) end
Private Instance Methods
_add(label, contents)
click to toggle source
# File lib/soroban/sheet.rb, line 79 def _add(label, contents) internal = "@#{label}" _expose(internal, label) cell = Cell.new(binding) _set(label, cell, contents) instance_variable_set(internal, cell) end
_bind(name, label)
click to toggle source
# File lib/soroban/sheet.rb, line 100 def _bind(name, label) @bindings[name.to_sym] = label.to_sym internal = "@#{label}" _expose(internal, name) end
_expose(internal, name)
click to toggle source
# File lib/soroban/sheet.rb, line 106 def _expose(internal, name) instance_eval <<-EOV, __FILE__, __LINE__ + 1 def #{name} _get("#{name}", #{internal}) end def #{name}=(contents) _set("#{name}", #{internal}, contents) end EOV end
_get(label_or_name, cell)
click to toggle source
# File lib/soroban/sheet.rb, line 92 def _get(label_or_name, cell) label = label_or_name.to_sym name = @cells[label] ? label : @bindings[label] badref = @cells[name] & missing raise Soroban::UndefinedError, "Unmet dependencies #{badref.join(', ')} for #{label}" if badref.length > 0 cell.get end
_set(label, cell, contents)
click to toggle source
# File lib/soroban/sheet.rb, line 87 def _set(label, cell, contents) cell.set(contents) @cells[label.to_sym] = cell.dependencies end