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