Skip to content

Instantly share code, notes, and snippets.

@jhawthorn
Created March 3, 2013 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhawthorn/5076846 to your computer and use it in GitHub Desktop.
Save jhawthorn/5076846 to your computer and use it in GitHub Desktop.
class Spreadsheet
def initialize
@hash = Hash.new(0)
end
class Subset < Struct.new(:spreadsheet, :row, :col)
def [] k
return k.map{|x| self[x]} if k.respond_to? :map
spreadsheet[cell k]
end
def []= k, v
return k.map{|x| self[x] = v} if k.respond_to? :map
spreadsheet[cell k] = v
end
def cell k; "#{self.col || k}#{self.row || k}"; end
end
def method_missing cell, *args
if cell =~ /\A([a-z]+)([0-9]+)=\Z/
@hash[[$1, $2]] = args.first
elsif cell =~ /\A([a-z]+)([0-9]+)\Z/
v = @hash[[$1, $2]]
v.is_a?(Proc) ? self.instance_eval(&v) : v
elsif cell =~ /\A([a-z]+)\Z/
Subset.new(self, nil, $1)
elsif cell =~ /\A_?([0-9]+)\Z/
Subset.new(self, $1, nil)
else
super
end
end
def []= key, value; method_missing("#{key}=", value); end
def [] key; method_missing(key.to_s); end
def to_s; @hash.to_s; end
end
ss = Spreadsheet.new
ss.a1 = Proc.new { a2 + a3 }
ss['a'][2..10] = 50 # assign a2 through a10
puts ss.a1
# => 100
ss['a']['1'] = Proc.new { a[2..20].inject(:+) }
puts ss['a1']
# => 450
ss.b1 = 'hello, world'
ss.d[1..20] = 'chunky bacon'
puts ss['1']['a'..'e'].inspect # print a1 through e1
# => [450, "hello, world", 0, "this fills row d", 0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment