module Eco module Language module Models class Wrap attr_reader :setters, :getters attr_reader :object def initialize(object = nil, setters: [], getters: []) @object = object self.setters = setters self.getters = getters end def getters=(value) @getters = into_a(value) @wgetters = wrap_object(@object, @getters) end def setters=(value) @setters = into_a(value) @wsetters = wrap_object(@object, @setters) end def object=(value) @object = value @wgetters = wrap_object(@object, @getters) @wsetters = wrap_object(@object, @setters) end def <<(value = []) value = into_a(value) @wsetters.each_with_index.map do |set, i| args = into_a(value[i]) set.call(*args) end end def row(value = (miss = true; [])) value = into_a(value) @wgetters.each_with_index.map do |get, i| args = into_a(value[i]) get.call(*args) unless miss get.call end end def wrap_object(object = nil, ops = []) object = object || @object return [] unless !!object into_a(ops).map do |op| cop = required_parameters?(op) ? curry(op) : op ->(*args) { args.unshift(object); #puts "calling wop: #{cop}, with args: #{args}, object: #{object}" cop[*args] #rescue nil } end end module Test class A attr_accessor :a, :e def initialize(val) self.a = val @e = 2 end def exp @a**@e end end end def self.test() # setters soa = ->(o,v) { o.a = v } soe = ->(o,v) { o.e = v } # getters goa = ->(o) { o.a } goe = ->(o) { o.e } goex = ->(o) { o.exp } # arrays setters = [soa, soe ] getters = [goa, goe, goex] a = Test::A.new(3) b = Test::A.new(5) w = self.new(a, setters: setters, getters: getters) puts "before check -> a: #{a.a}; e: #{a.e}; exp: #{a.exp}" # launch setters w << [4, 2] puts "after setters -> a: #{a.a}; e: #{a.e}; exp: #{a.exp}" # launch getters a, e, exp = w.row puts "from getters(a) -> a: #{a}; e: #{e}; exp: #{exp}" # switch object w.object = b # launch getters a, e, exp = w.row puts "from getters(b) -> a: #{a}; e: #{e}; exp: #{exp}" end private def into_a(value) value = [].push(value) unless value.is_a?(Array) value end end end end end