lib/moosex.rb in moosex-0.0.8 vs lib/moosex.rb in moosex-0.0.9

- old
+ new

@@ -16,15 +16,24 @@ define_singleton_method(:__meta) { meta } end def initialize(args={}) + args = BUILDARGS(args) self.class.__meta().init(self, args) + BUILD() end + def BUILDARGS(args) + args + end + + def BUILD + end + def c.inherited(subclass) subclass.class_exec do old_meta = subclass.__meta meta = MooseX::Meta.new(old_meta.attrs) @@ -92,12 +101,14 @@ DEFAULTS= { lazy: false, clearer: false, required: false, predicate: false, - isa: lambda { |x| true }, + isa: lambda { |value| true }, handles: {}, + trigger: lambda {|object,value|}, # TODO: implement + coerce: lambda {|object| object}, # TODO: implement } REQUIRED = [ :is ] VALIDATE = { @@ -216,15 +227,34 @@ builder end, init_arg: lambda do |init_arg, field_name| init_arg.to_sym end, + trigger: lambda do |trigger, field_name| + unless trigger.is_a? Proc + trigger_method_name = trigger.to_sym + trigger = lambda do |object, value| + object.send(trigger_method_name,value) + end + end + + trigger + end, + coerce: lambda do |coerce, field_name| + unless coerce.is_a? Proc + coerce_method_name = coerce.to_sym + coerce = lambda do |object| + object.send(coerce_method_name) + end + end + + coerce + end, }; def initialize(a, o) # todo extract this to a framework, see issue #21 on facebook - o = DEFAULTS.merge({ reader: a, writter: a.to_s.concat("=").to_sym, builder: "build_#{a}".to_sym, init_arg: a, @@ -265,10 +295,12 @@ @lazy = o[:lazy] @reader = o[:reader] @writter = o[:writter] @builder = o[:builder] @init_arg = o[:init_arg] + @trigger = o[:trigger] + @coerce = o[:coerce] end def init(object, args) inst_variable_name = "@#{@attr_symbol}".to_sym @@ -293,51 +325,51 @@ remove_instance_variable inst_variable_name end end end + value_from_default = false if args.has_key? @init_arg value = args[ @init_arg ] elsif @default value = @default.call + value_from_default = true elsif @required raise "attr \"#{@attr_symbol}\" is required" else return end - if @is.eql?(:ro) || @is.eql?(:lazy) - # TODO: remove redundancy + value = @coerce.call(value) - type_check = @isa - type_check.call(value) - - object.instance_variable_set inst_variable_name, value + @isa.call( value ) + unless value_from_default + @trigger.call(object, value) + end - else - - object.send( @writter, value ) - - end + object.instance_variable_set inst_variable_name, value + end def generate_getter inst_variable_name = "@#{@attr_symbol}".to_sym builder = @builder before_get = lambda {|object| } if @lazy type_check = @isa - + coerce = @coerce + trigger = @trigger before_get = lambda do |object| return if object.instance_variable_defined? inst_variable_name value = builder.call(object) + value = coerce.call(value) type_check.call(value) - + trigger.call(object, value) object.instance_variable_set(inst_variable_name, value) end end Proc.new do @@ -346,12 +378,16 @@ end end def generate_setter inst_variable_name = "@#{@attr_symbol}".to_sym + coerce = @coerce type_check = @isa + trigger = @trigger Proc.new do |value| + value = coerce.call(value) type_check.call(value) + trigger.call(self,value) instance_variable_set inst_variable_name, value end end end end \ No newline at end of file