Class: Params::Registry::Group

Inherits:
Object
  • Object
show all
Defined in:
lib/params/registry.rb

Overview

A group is an identifiable sequence of parameters.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(registry, id, templates: nil) ⇒ Group

Create a new group.

Parameters:



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

#idObject (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

#registryObject (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.

Parameters:

  • id (Object)

    the template identifier, either canonical or an alias.

Returns:



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.

Parameters:

  • id (Object)

    the template's canonical identifier.

  • spec (Hash{Symbol => Object}, Params::Registry::Template, nil)

    the template specification, as described above.

Returns:



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.

Parameters:

  • id (Object)

    the identifier, canonical or otherwise.

Returns:

  • (Object, nil)

    the canonical identifier, if found.



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.

Parameters:

  • id (Object)

    the canonical identifier for the template, or an alias.

Returns:



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

#inspectString

Return a suitable representation for debugging.

Returns:

  • (String)

    the object.



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.

Returns:

  • (false, true)

    what I said.



122
123
124
# File 'lib/params/registry.rb', line 122

def key? id
  !!self[id]
end

#keysArray

Return the canonical template identifiers.

Returns:

  • (Array)

    the keys.



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.

Parameters:

  • params

    [String, URI, Hash=> Array, Array>] the parameter set, in a dizzying variety of inputs.

Returns:



220
221
222
# File 'lib/params/registry.rb', line 220

def process params
  registry.instance_class.new self, Types::Input[params]
end

#rankedArray<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.

Returns:



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

#templatesArray<Params::Registry::Template>

Return the template entries, in order.

Returns:



136
# File 'lib/params/registry.rb', line 136

def templates ; @templates.values; end