lib/french_man.rb in french_man-0.0.2 vs lib/french_man.rb in french_man-0.0.3

- old
+ new

@@ -15,32 +15,52 @@ # => 'francois' # # login.password # => 'baguette' class FrenchMan - VERSION = "0.0.2" + VERSION = "0.0.3" def self.const_missing(name) #:nodoc: clazz = Class.new do def self.blueprint(&block) blueprint = Blueprint.new &block send(:class_variable_set, :@@blueprint, blueprint) end - def self.plan(&block) + def self.plan(hash = nil, &block) blueprint = send(:class_variable_get, :@@blueprint) raise "blueprint is missing" if blueprint.nil? - plan = Plan.new &block + plan = hash.nil? ? Plan.new(&block) : HashBuild.new(hash) blueprint.merge plan.hash end end self.const_set name, clazz end + class HashBuild + def initialize(hash) + @hash = hash || {} + end + + def hash + result = {} + @hash.each_pair do |key, value| + key_string = key.to_s.capitalize + if FrenchMan.const_defined? key_string + blueprint = FrenchMan.const_get key_string + result.merge! key => blueprint.plan(value) + else + result.merge! key => value + end + end + ObjectifiedHash.new result + end + end + # Creates a new plan hash for merging with a blueprint class Plan - undef_method :id + undef_method :id if method_defined?(:id) attr_reader :hash def initialize(&block) #:nodoc: @hash = {} @@ -52,11 +72,12 @@ end end # The blueprint to create hashes from class Blueprint - undef_method :id, :type + undef_method :id if method_defined?(:id) + undef_method :type if method_defined?(:type) def initialize(&block) #:nodoc: @hash = {} instance_eval &block end @@ -75,20 +96,36 @@ def method_missing(attribute, &block) #:nodoc: @hash.merge!(attribute => block) end end - # Wraper for plan hashes so dot syntax can be used class ObjectifiedHash - undef_method :==, :===, :=~, :id + undef_method :id if method_defined?(:id) + undef_method :==, :===, :=~ def initialize(attributes = {}) #:nodoc: @attributes = attributes end + def to_hash + hash = {} + @attributes.each do |key, val| + if val.is_a? Array + hash[key] = val.map { |elmt| (elmt.respond_to? 'to_hash') ? elmt.to_hash : elmt } + else + hash[key] = (val.respond_to? 'to_hash') ? val.to_hash : val + end + end + hash + end + + def to_json(options={}) # by default Object.to_json return 'attributes' root key + to_hash.to_json(options) + end + def method_missing(name, *args) #:nodoc: if @attributes.has_key? name - value = @attributes[name] + value = name.is_a?(Hash) ? self.class.new(@attributes[name]) : @attributes[name] else @attributes.send name, *args end end end