lib/moosex.rb in moosex-0.0.14 vs lib/moosex.rb in moosex-0.0.15
- old
+ new
@@ -7,41 +7,59 @@
#
require "moosex/version"
require "moosex/types"
module MooseX
- $MOOSEX_DEBUG = true
+ @@MOOSEX_WARNINGS = true
+ @@MOOSEX_FATAL = false
+
+ class FatalError < StandardError
+ end
+
+ def self.warn(x, *c)
+ raise FatalError, "[MooseX] exception: #{x}",*c if @@MOOSEX_FATAL
+ Kernel.warn("[MooseX] warning: #{x}") if @@MOOSEX_WARNINGS
+ end
+
+ def self.init(args={})
+ if args.has_key? :warnings
+ @@MOOSEX_WARNINGS = !! args[:warnings]
+ end
+
+ if args.has_key? :fatal
+ @@MOOSEX_FATAL = !! args[:fatal]
+ end
+
+ self
+ end
- def MooseX.enable_warnings()
- $MOOSEX_DEBUG = false
- MooseX
- end
-
- def MooseX.disable_warnings()
- $MOOSEX_DEBUG = false
- MooseX
- end
-
class RequiredMethodNotFoundError < NameError
end
def MooseX.included(c)
c.extend(MooseX::Core)
+
+ def c.init(*args)
+ __meta.roles.each{|role| role.call(*args)}
+
+ self
+ end
def c.included(x)
+
MooseX.included(x)
x.__meta.load_from(self.__meta)
return unless x.is_a? Class
x.__meta.load_hooks(self.__meta)
self.__meta.init_klass(x)
x.__meta.requires.each do |method|
unless x.public_instance_methods.include? method
- warn "[MooseX] you must implement method '#{method}' in #{x} #{x.class}: required" if $MOOSEX_DEBUG
+ MooseX.warn "you must implement method '#{method}' in #{x} #{x.class}: required"# if $MOOSEX_DEBUG
end
end
end
meta = MooseX::Meta.new
@@ -78,16 +96,17 @@
end
end
class Meta
- attr_reader :attrs, :requires, :before, :after, :around
+ attr_reader :attrs, :requires, :before, :after, :around, :roles
def initialize(old_meta=nil)
@initialized = false
@attrs = {}
@requires = []
+ @roles = []
@before = Hash.new { |hash, key| hash[key] = [] }
@after = Hash.new { |hash, key| hash[key] = [] }
@around = Hash.new { |hash, key| hash[key] = [] }
if old_meta
@@ -134,17 +153,26 @@
end
def add_around(method_name, block)
@around[method_name] << block.clone
end
+
+ def add_role(block)
+ @roles << block
+ end
def init_klass(klass)
#return if @initialized
[@before.keys + @after.keys + @around.keys].flatten.uniq.each do |method_name|
- method = klass.instance_method method_name
-
+ begin
+ method = klass.instance_method method_name
+ rescue => e
+ MooseX.warn "Unable to apply hooks (after/before/around) in #{klass}::#{method_name} : #{e}" # if $MOOSEX_DEBUG
+ next
+ end
+
before = @before[method_name]
after = @after[method_name]
around = @around[method_name]
klass.__meta_define_method(method_name) do |*args|
@@ -166,11 +194,11 @@
end
def init(object, args)
@attrs.each_pair{ |symbol, attr| attr.init(object, args) }
- warn "[MooseX] unused attributes #{args} for #{object.class}" if $MOOSEX_DEBUG && ! args.empty?
+ MooseX.warn "unused attributes #{args} for #{object.class}", caller unless args.empty?
@requires.each do |method|
unless object.respond_to? method
raise RequiredMethodNotFoundError,
"you must implement method '#{method}' in #{object.class}: required"
@@ -178,53 +206,66 @@
end
end
end
module Core
- def after(method_name, &block)
- begin
- method = instance_method method_name
+ def on_init(&block)
+ __meta.add_role(block)
+ end
+
+ def after(*methods_name, &block)
+ methods_name.each do |method_name|
+ begin
+ method = instance_method method_name
- define_method method_name do |*args|
- result = method.bind(self).call(*args)
- block.call(self,*args)
- result
- end
- rescue => e
- __meta.add_after(method_name, block)
- end
+ define_method method_name do |*args|
+ result = method.bind(self).call(*args)
+ block.call(self,*args)
+ result
+ end
+ rescue => e
+ MooseX.warn "unable to apply hook after in #{method_name} @ #{self}: #{e}", caller() if self.is_a?(Class)
+ __meta.add_after(method_name, block)
+ end
+ end
end
- def before(method_name, &block)
- begin
- method = instance_method method_name
+ def before(*methods_name, &block)
+ methods_name.each do |method_name|
+ begin
+ method = instance_method method_name
- define_method method_name do |*args|
- block.call(self,*args)
- method.bind(self).call(*args)
- end
- rescue => e
- __meta.add_before(method_name, block)
- end
+ define_method method_name do |*args|
+ block.call(self,*args)
+ method.bind(self).call(*args)
+ end
+ rescue => e
+ MooseX.warn "unable to apply hook before in #{method_name} @ #{self}: #{e}", caller() if self.is_a?(Class)
+ __meta.add_before(method_name, block)
+ end
+ end
end
- def around(method_name, &block)
- begin
- method = instance_method method_name
+ def around(*methods_name, &block)
+ methods_name.each do |method_name|
+ begin
+ method = instance_method method_name
- code = Proc.new do | o, *a|
- method.bind(o).call(*a)
- end
+ code = Proc.new do | o, *a|
+ method.bind(o).call(*a)
+ end
- define_method method_name do |*args|
+ define_method method_name do |*args|
- block.call(code, self,*args)
+ block.call(code, self,*args)
- end
- rescue => e
- __meta.add_around(method_name, block)
- end
+ end
+ rescue => e
+ MooseX.warn "unable to apply hook around in #{method_name} @ #{self}: #{e}", caller() if self.is_a?(Class)
+ __meta.add_around(method_name, block)
+ end
+ end
end
def requires(*methods)
methods.each do |method_name|
@@ -414,11 +455,11 @@
coerce
end,
};
- def initialize(a, o, x)
+ def initialize(a, o ,x)
#o ||= {}
# todo extract this to a framework, see issue #21 on facebook
o = DEFAULTS.merge({
reader: a,
writter: a.to_s.concat("=").to_sym,
@@ -468,10 +509,10 @@
@init_arg = o.delete(:init_arg)
@trigger = o.delete(:trigger)
@coerce = o.delete(:coerce)
@methods = {}
- warn "[MooseX] unused attributes #{o} for attribute #{a} @ #{x} #{x.class}" if $MOOSEX_DEBUG && ! o.empty?
+ MooseX.warn "Unused attributes #{o} for attribute #{a} @ #{x} #{x.class}",caller() if ! o.empty?
if @reader
@methods[@reader] = generate_reader
end
\ No newline at end of file