lib/configurable/delegate_hash.rb in configurable-0.4.2 vs lib/configurable/delegate_hash.rb in configurable-0.5.0
- old
+ new
@@ -58,14 +58,14 @@
end
# Binds self to the specified receiver. Delegate values are removed from
# store and sent to their writer on receiver. If the store has no value
# for a delegate key, the delegate default value will be used.
- def bind(receiver)
+ def bind(receiver, rebind=false)
raise ArgumentError, "receiver cannot be nil" if receiver == nil
- if bound?
+ if bound? && !rebind
if @receiver == receiver
return(self)
else
raise ArgumentError, "already bound to: #{@receiver}"
end
@@ -150,14 +150,22 @@
another.respond_to?(:to_hash) && to_hash == another.to_hash
end
# Returns self as a hash. Any DelegateHash values are recursively
# hashified, to account for nesting.
- def to_hash
+ def to_hash(&block)
hash = {}
each_pair do |key, value|
- hash[key] = value.kind_of?(DelegateHash) ? value.to_hash : value
+ if value.kind_of?(DelegateHash)
+ value = value.to_hash(&block)
+ end
+
+ if block_given?
+ yield(hash, key, value)
+ else
+ hash[key] = value
+ end
end
hash
end
# Overrides default inspect to show the to_hash values.
@@ -176,18 +184,33 @@
protected
# helper to map delegate values from source to the receiver
def map(source) # :nodoc:
+ source_values = {}
+ source.each_key do |key|
+ if delegate = delegates[key]
+ if source_values.has_key?(delegate)
+ key = delegates.keys.find {|k| delegates[k] == delegate }
+ raise "multiple values mapped to #{key.inspect}"
+ end
+
+ source_values[delegate] = source.delete(key)
+ end
+ end
+
delegates.each_pair do |key, delegate|
# map the value; if no value is set in the source then use the
# delegate default. if map_default is false, then simply skip...
# this ensures each config is initialized to a value when bound
# UNLESS map_default is set (indicating manual initialization)
value = case
- when source.has_key?(key) then source.delete(key)
- when delegate[:set_default, true] then delegate.default
- else next
+ when source_values.has_key?(delegate)
+ source_values[delegate]
+ when delegate[:set_default, true]
+ delegate.default
+ else
+ next
end
receiver.send(delegate.writer, value)
end
end
\ No newline at end of file