Class: Params::Registry::Group
- Inherits:
-
Object
- Object
- Params::Registry::Group
- Extended by:
- Forwardable
- Defined in:
- lib/params/registry.rb
Overview
A group is an identifiable sequence of parameters.
Instance Attribute Summary collapse
-
#id ⇒ Object
readonly
!@attribute [r] id @return [Object] the identifier of the group.
-
#registry ⇒ Object
readonly
!@attribute [r] id @return [Object] the identifier of the group.
Instance Method Summary collapse
-
#[](id) ⇒ Params::Registry::Template?
Retrieve a template.
-
#[]=(id, spec) ⇒ Params::Registry::Template
Add a parameter template to the group.
-
#canonical(id) ⇒ Object?
Return the canonical identifier for the template.
-
#delete(id) ⇒ Params::Registry::Template?
Delete a template from the group.
-
#initialize(registry, id, templates: nil) ⇒ Group
constructor
Create a new group.
-
#inspect ⇒ String
Return a suitable representation for debugging.
-
#key?(id) ⇒ false, true
Return whether the group has a given key.
-
#keys ⇒ Array
Return the canonical template identifiers.
-
#process(params, defaults: true, force: false) ⇒ Params::Registry::Instance
Process the parameters and return a Instance.
-
#ranked ⇒ Array<Hash{Object => Params::Registry::Template}>
Return an array of arrays of templates sorted by rank.
-
#templates ⇒ Array<Params::Registry::Template>
Return the template entries, in order.
-
#templates=(templates) ⇒ Array, Hash
Assign a new sequence of templates to the group.
Constructor Details
#initialize(registry, id, templates: nil) ⇒ Group
Create a new group.
31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/params/registry.rb', line 31 def initialize registry, id, templates: nil @id = id @registry = registry @templates = {} # main mapping @aliases = {} # alternate mapping @ranks = {} # internal ranking for dependencies templates = (Types::Array|Types::TemplateMap)[templates] # use the internal subscript assignment templates.each { |t, spec| self[t] = spec || t } end |
Instance Attribute Details
#id ⇒ Object (readonly)
!@attribute [r] id @return [Object] the identifier of the group.
!@attribute [r] registry @return [Params::Registry] the associated registry.
50 51 52 |
# File 'lib/params/registry.rb', line 50 def id @id end |
#registry ⇒ Object (readonly)
!@attribute [r] id @return [Object] the identifier of the group.
!@attribute [r] registry @return [Params::Registry] the associated registry.
50 51 52 |
# File 'lib/params/registry.rb', line 50 def registry @registry end |
Instance Method Details
#[](id) ⇒ Params::Registry::Template?
Retrieve a template.
58 59 60 |
# File 'lib/params/registry.rb', line 58 def [] id @templates[id] || @aliases[id] end |
#[]=(id, spec) ⇒ Params::Registry::Template
Add a parameter template to the group. The spec
can be a
template specification, or it can be an already-instantiated
template, or it can be the same as id
, or it can be nil
. In
the first case, the template will be created and added to the
registry, replacing any template with the same ID. In the case
that it's a Template instance, its ID must
match id
and it must come from the same registry as the
group. In the latter two cases, the parameter is retrieved from
the registry, raising an exception if not.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/params/registry.rb', line 79 def []= id, spec case spec when nil, id template = registry.templates[id] raise ArgumentError, "Could not find template #{id}" unless template when Template raise ArgumentError, "Template #{id} supplied from some other registry" unless registry.equal? spec.registry raise ArgumentError, "Identifier #{id} does not match template (#{spec.id})" unless id == spec.id template = spec else Types::Hash[spec] template = registry.template_class.new registry, id, **spec end # make sure we aren't calling ourselves registry.templates[id] = template unless registry.templates.equal? self # okay now actually assign @templates[id] = template # then map all the aliases and crap @aliases[template.slug] = template if template.slug # we use a conditional assign here since aliases take a lower priority template.aliases.each { |a| @aliases[a] ||= template } # now we compute the rank, but first we need the dependencies deps = template.depends.map do |t| registry.templates[t] end.compact.map(&:id) # warn deps.inspect # XXX this does not do cycles; we should really do cycles. rank = @ranks.values_at(*deps).compact.max @ranks[id] = rank.nil? ? 0 : rank + 1 # warn template.id template end |
#canonical(id) ⇒ Object?
Return the canonical identifier for the template.
174 175 176 177 |
# File 'lib/params/registry.rb', line 174 def canonical id return id if @templates.key? id @aliases[id].id if @aliases.key? id end |
#delete(id) ⇒ Params::Registry::Template?
Delete a template from the group.
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/params/registry.rb', line 208 def delete id # first we have to find it return unless template = self[id] @templates.delete template.id @ranks.delete template.id @aliases.delete template.slug if template.slug # XXX i feel like we should try to find other parameters that # may have an alias that's the same as the one we just deleted # and give (the first matching one) the now-empty slot, but # that's not urgent so i'll leave it for now. template.aliases.each do |a| @aliases.delete a if template.equal? @aliases[a] end # if we are the main registry group we have to do extra stuff if registry.templates.equal? self registry.groups.each { |g| g.delete template.id } end # this leaves us with an unbound template which i gueessss we # could reinsert? template end |
#inspect ⇒ String
Return a suitable representation for debugging.
238 239 240 |
# File 'lib/params/registry.rb', line 238 def inspect "#<#{self.class}: #{id} {#{keys.join ', '}}>" end |
#key?(id) ⇒ false, true
Return whether the group has a given key.
127 128 129 |
# File 'lib/params/registry.rb', line 127 def key? id !!self[id] end |
#keys ⇒ Array
Return the canonical template identifiers.
135 |
# File 'lib/params/registry.rb', line 135 def keys ; @templates.keys; end |
#process(params, defaults: true, force: false) ⇒ Params::Registry::Instance
Process the parameters and return a Instance.
254 255 256 257 |
# File 'lib/params/registry.rb', line 254 def process params, defaults: true, force: false registry.instance_class.new self, params: params, defaults: defaults, force: force end |
#ranked ⇒ Array<Hash{Object => Params::Registry::Template}>
Return an array of arrays of templates sorted by rank. A higher rank means a parameter depends on one or more parameters with a lower rank.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/params/registry.rb', line 186 def ranked # warn @ranks.inspect out = Array.new((@ranks.values.max || -1) + 1) { {} } # warn out.inspect @templates.values.reject do |t| # skip the complement as it's handled out of band t.equal? registry.complement end.each { |t| out[@ranks[t.id]][t.id] = t } out end |
#templates ⇒ Array<Params::Registry::Template>
Return the template entries, in order.
141 |
# File 'lib/params/registry.rb', line 141 def templates ; @templates.values; end |
#templates=(templates) ⇒ Array, Hash
Assign a new sequence of templates to the group.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/params/registry.rb', line 150 def templates= templates templates = templates.to_a if templates.is_a? Hash raise ArgumentError, "Don't know what to do with #{templates.class}" unless templates.respond_to? :to_a # empty out the actual instance member @templates.clear # this should destructure appropriately (XXX MAYBE???) and also # use the overloaded subscript assignment method templates.to_a.each { |id, spec| self[id] = spec || id } # now return the new members @templates.values end |