pakyow-presenter/lib/presenter/binder.rb in pakyow-presenter-0.8.0 vs pakyow-presenter/lib/presenter/binder.rb in pakyow-presenter-0.9.0
- old
+ new
@@ -1,79 +1,89 @@
+require 'singleton'
+
module Pakyow
module Presenter
- # A singleton that manages route sets.
+ # A singleton that manages BinderSet instances for an app. It handles
+ # the creation / registration of sets and provides a mechanism
+ # to augment data to be bound with values from the sets.
#
class Binder
include Singleton
- include Helpers
+ # Access to the registered binder sets for an app.
+ #
attr_reader :sets
def initialize
@sets = {}
end
- #TODO want to do this for all sets?
+ # Resets the registered binder sets.
+ #
+ # @return [Binder] the reset instance
+ #
def reset
@sets = {}
self
end
- # Creates a new set.
+ # Creates and registers a new binder set by name. A block should be passed
+ # that defines the bindings. This block will be evaluated in context
+ # of the created binder set.
#
+ # @see BinderSet
+ #
+ # @param name [Symbol] the name of the binder set to be created
+ #
def set(name, &block)
- @sets[name] = BinderSet.new
- @sets[name].instance_exec(&block)
+ @sets[name] = BinderSet.new(&block)
end
- def value_for_prop(prop, scope, bindable, bindings = {}, context)
- @context = context
- binding = nil
- @sets.each {|set|
- binding = set[1].match_for_prop(prop, scope, bindable, bindings)
- break if binding
+ # Returns the value for the scope->prop by applying any defined bindings to the data.
+ #
+ # @param scope [Symbol] the scope name
+ # @param prop [Symbol] the prop name
+ # @param bindable [Symbol] the data being bound
+ # @param bindings [Symbol] additional bindings to take into consideration when determining the value
+ # @param context [Symbol] context passed through to the defined bindings
+ #
+ def value_for_scoped_prop(scope, prop, bindable, bindings, context)
+ binding_fn = @sets.lazy.map { |set|
+ set[1].match_for_prop(prop, scope, bindable, bindings)
+ }.find { |match|
+ !match.nil?
}
- if binding
+ if binding_fn
binding_eval = BindingEval.new(prop, bindable, context)
-
- case binding.arity
- when 0
- binding_eval.instance_exec(&binding)
- when 1
- self.instance_exec(bindable, &binding)
- when 2
- self.instance_exec(bindable, binding_eval.value, &binding)
+ binding_eval.instance_exec(binding_eval.value, bindable, context, &binding_fn)
+ else # default value
+ if bindable.is_a?(Hash)
+ bindable[prop]
+ elsif bindable.class.method_defined?(prop)
+ bindable.send(prop)
end
- else
- # default
- prop_value_for_bindable(bindable, prop)
end
end
- def prop_value_for_bindable(bindable, prop)
- return bindable[prop] if bindable.is_a?(Hash)
- return bindable.send(prop) if bindable.class.method_defined?(prop)
- end
-
- def options_for_prop(*args)
- match = nil
- @sets.each {|set|
- match = set[1].options_for_prop(*args)
- break if match
+ # Returns true if a binding is defined for the scope->prop.
+ #
+ def has_scoped_prop?(scope, prop, bindings)
+ @sets.lazy.map { |set|
+ set[1].has_prop?(scope, prop, bindings)
+ }.find { |has_prop|
+ has_prop
}
-
- return match
end
- def has_prop?(*args)
- has = nil
- @sets.each {|set|
- has = set[1].has_prop?(*args)
- break if has
+ # Returns options for the scope->prop.
+ #
+ def options_for_scoped_prop(scope, prop, bindable, context)
+ @sets.lazy.map { |set|
+ set[1].options_for_prop(scope, prop, bindable, context)
+ }.find { |options|
+ !options.nil?
}
-
- return has
end
end
end
end