Class: Params::Registry::Group
- Inherits:
-
Object
- Object
- Params::Registry::Group
- 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) ⇒ 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.
Constructor Details
#initialize(registry, id, templates: nil) ⇒ Group
Create a new group.
26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/params/registry.rb', line 26 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.
45 46 47 |
# File 'lib/params/registry.rb', line 45 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.
45 46 47 |
# File 'lib/params/registry.rb', line 45 def registry @registry end |
Instance Method Details
#[](id) ⇒ Params::Registry::Template?
Retrieve a template.
53 54 55 |
# File 'lib/params/registry.rb', line 53 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.
74 75 76 77 78 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 |
# File 'lib/params/registry.rb', line 74 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.
144 145 146 147 |
# File 'lib/params/registry.rb', line 144 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.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/params/registry.rb', line 178 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.
208 209 210 |
# File 'lib/params/registry.rb', line 208 def inspect "#<#{self.class}: #{id} {#{keys.join ', '}}>" end |
#key?(id) ⇒ false, true
Return whether the group has a given key.
122 123 124 |
# File 'lib/params/registry.rb', line 122 def key? id !!self[id] end |
#keys ⇒ Array
Return the canonical template identifiers.
130 |
# File 'lib/params/registry.rb', line 130 def keys ; @templates.keys; end |
#process(params) ⇒ Params::Registry::Instance
Process the parameters and return a Instance.
220 221 222 |
# File 'lib/params/registry.rb', line 220 def process params registry.instance_class.new self, Types::Input[params] 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.
156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/params/registry.rb', line 156 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.
136 |
# File 'lib/params/registry.rb', line 136 def templates ; @templates.values; end |