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