lib/option_initializer.rb in option_initializer-1.1.4 vs lib/option_initializer.rb in option_initializer-1.2.0

- old
+ new

@@ -1,8 +1,68 @@ require "option_initializer/version" module OptionInitializer + class OptionInitializingTemplate + attr_reader :options + alias to_h options + + const_set :VALIDATORS, [] + + def initialize base, options, need_validation + validate options if need_validation + @base = base + @options = options + end + + def new *args, &block + args = args.dup + opts = @options + + # Convention. Deal with it. + if args.last.is_a?(Hash) + validate args.last + opts = opts.merge(args.last) + args.pop + else + opts = opts.dup + end + + opts.instance_eval do + def option_validated? + true + end + end + args << opts + + @base.new(*args, &block) + end + + def merge opts + validate opts + self.class.new @base, @options.merge(opts), false + end + + def validate hash + self.class.const_get(:VALIDATORS).each do |validator| + hash.each do |k, v| + validator.call k, v + end + end + end + end + + module MethodCallShortcut + def method_missing sym, *args, &block + # 1.8 + if @base.instance_methods.map(&:to_sym).include?(sym) + new.send sym, *args, &block + else + raise NoMethodError, "undefined method `#{sym}' for #{self}" + end + end + end + def validate_options options raise TypeError, "wrong argument type #{options.class} (expected Hash)" unless options.is_a?(Hash) return if options.respond_to?(:option_validated?) @@ -14,71 +74,17 @@ end options end def self.included base - base.const_set :OptionInitializing, Class.new { - attr_reader :options - alias to_h options + unless base.constants.map(&:to_sym).include?(:OptionInitializing) + base.const_set :OptionInitializing, OptionInitializingTemplate.dup + end - const_set :VALIDATORS, [] - - def initialize base, options, need_validation - validate options if need_validation - @base = base - @options = options - end - - def new *args, &block - args = args.dup - opts = @options - - # Convention. Deal with it. - if args.last.is_a?(Hash) - validate args.last - opts = opts.merge(args.last) - args.pop - else - opts = opts.dup - end - - opts.instance_eval do - def option_validated? - true - end - end - args << opts - - @base.new(*args, &block) - end - - def merge opts - validate opts - self.class.new @base, @options.merge(opts), false - end - - def validate hash - self.class.const_get(:VALIDATORS).each do |validator| - hash.each do |k, v| - validator.call k, v - end - end - end - - def method_missing sym, *args, &block - # 1.8 - if @base.instance_methods.map(&:to_sym).include?(sym) - new.send sym, *args, &block - else - raise NoMethodError, "undefined method `#{sym}' for #{self}" - end - end - } unless base.constants.map(&:to_sym).include?(:OptionInitializing) - base.class_eval do class << self - [:option_initializer, :option_validator].each do |m| + [:option_initializer, :option_initializer!, :option_validator].each do |m| undef_method(m) if method_defined?(m) end end def base.option_validator &block @@ -131,9 +137,16 @@ end end end end end + + def base.option_initializer! *syms + option_initializer(*syms) + oi = self.const_get(:OptionInitializing) + oi.class_eval do + include OptionInitializer::MethodCallShortcut + end + end end end end -