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

- old
+ new

@@ -1,10 +1,12 @@ # Module MooseX -# A postmodern object system for Ruby +# A postmodern object DSL for Ruby # -# MooseX is an extension of Ruby object system. The main goal of MooseX is to make Ruby Object Oriented programming easier, more consistent, and less tedious. With MooseX you can think more about what you want to do and less about the mechanics of OOP. It is a port of Moose/Moo from Perl to Ruby world. - +# Author:: Tiago Peczenyj (mailto:tiago.peczenyj@gmail.com) +# Copyright:: Copyright (c) 2014 Tiago Peczenyj +# License:: MIT +# require "moosex/version" module MooseX def MooseX.included(c) @@ -15,20 +17,20 @@ meta = MooseX::Meta.new define_singleton_method(:__meta) { meta } end - def initialize(args={}) - args = BUILDARGS(args) + def initialize(*args) + args = BUILDARGS(*args) + + self.class.__meta().init(self, args || {}) - self.class.__meta().init(self, args) - BUILD() end - def BUILDARGS(args) - args + def BUILDARGS(*args) + args[0] end def BUILD end @@ -72,34 +74,29 @@ end else attr = MooseX::Attribute.new(attr_name, attr_options) - g = attr.generate_getter - - define_method attr.reader, &g - - s = attr.generate_setter - - case attr.is - when :rw - define_method attr.writter, &s - - when :rwp - define_method attr.writter, &s - + attr.methods.each_pair do |method, proc| + define_method method, &proc + end + + if attr.is.eql?(:rwp) private attr.writter + elsif attr.is.eql?(:private) + private attr.writter + private attr.reader end __meta.add(attr) end end end class Attribute - attr_reader :attr_symbol, :is, :reader, :writter, :lazy, :builder + attr_reader :attr_symbol, :is, :reader, :writter, :lazy, :builder, :methods DEFAULTS= { lazy: false, clearer: false, required: false, predicate: false, @@ -111,12 +108,12 @@ REQUIRED = [ :is ] VALIDATE = { is: lambda do |is, field_name| - unless [:rw, :rwp, :ro, :lazy].include?(is) - raise "invalid value for field '#{field_name}' is '#{is}', must be one of :rw, :rwp, :ro or :lazy" + unless [:rw, :rwp, :ro, :lazy, :private].include?(is) + raise "invalid value for field '#{field_name}' is '#{is}', must be one of :private, :rw, :rwp, :ro or :lazy" end end, }; COERCE = { @@ -159,11 +156,11 @@ end, clearer: lambda do|clearer, field_name| if ! clearer return false elsif clearer.is_a? TrueClass - return "reset_#{field_name}!".to_sym + return "clear_#{field_name}!".to_sym end begin clearer.to_sym rescue => e @@ -250,10 +247,11 @@ coerce end, }; def initialize(a, o) + #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, @@ -274,17 +272,20 @@ return if ! o.has_key? field validate.call(o[field], a) end - if o[:is].eql? :lazy + if o[:is].eql? :ro + o[:writter] = nil + elsif o[:is].eql? :lazy o[:lazy] = true + o[:writter] = nil end unless o[:lazy] o[:builder] = nil - end + end @attr_symbol = a @is = o[:is] @isa = o[:isa] @default = o[:default] @@ -297,39 +298,46 @@ @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 - - value = nil + @methods = {} - attr_symbol = @attr_symbol - @handles.each_pair do | method, target_method | - object.define_singleton_method method do |*args| - self.send(attr_symbol).send(target_method, *args) - end + if @reader + @methods[@reader] = generate_reader end - + + if @writter + @methods[@writter] = generate_writter + end + inst_variable_name = "@#{@attr_symbol}".to_sym if @predicate - object.define_singleton_method @predicate do + @methods[@predicate] = Proc.new do instance_variable_defined? inst_variable_name end end if @clearer - object.define_singleton_method @clearer do + @methods[@clearer] = Proc.new do if instance_variable_defined? inst_variable_name remove_instance_variable inst_variable_name end end end - + + attr_symbol = @attr_symbol + @handles.each_pair do | method, target_method | + @methods[method] = Proc.new do |*args| + self.send(attr_symbol).send(target_method, *args) + end + end + end + + def init(object, args) + value = nil value_from_default = false + if args.has_key? @init_arg value = args[ @init_arg ] elsif @default value = @default.call value_from_default = true @@ -345,15 +353,16 @@ @isa.call( value ) unless value_from_default @trigger.call(object, value) end + inst_variable_name = "@#{@attr_symbol}".to_sym object.instance_variable_set inst_variable_name, value - end - - def generate_getter + + private + def generate_reader inst_variable_name = "@#{@attr_symbol}".to_sym builder = @builder before_get = lambda {|object| } @@ -376,10 +385,10 @@ before_get.call(self) instance_variable_get inst_variable_name end end - def generate_setter + def generate_writter inst_variable_name = "@#{@attr_symbol}".to_sym coerce = @coerce type_check = @isa trigger = @trigger Proc.new do |value| \ No newline at end of file