Class: Nero::BaseTag

Inherits:
Object
  • Object
show all
Includes:
Resolvable
Defined in:
lib/nero.rb

Overview

Superclass for all tags.

Writing your own tag-class would look something like this:

Wanted usage in YAML:

Nero.load(<<~YAML)
  secret: !rot/12 "some message"
  other_secret: !rot/13 [ !env [SECRET, some message] ]
YAML

Required config:

config.add_tag("rot/12", klass: RotTag[n: 12])
config.add_tag("rot/13", klass: RotTag[n: 13]) do |secret|
  "#{secret} (try breaking this!)"
end

The class then would look like this:

class RotTag < Nero::BaseTag
  attr_reader :n

  # Overriding this method...:
  # - restricts options
  #   ie `RotTag[x: 1]` would raise.
  # - sets default values
  # - makes options available via getters
  #   (otherwise available via `options[:n]`).
  def init_options(n: 10)
    super
    @n = n
  end

  # This is where the magic happens.
  # (Accepting any keyword arguments keeps the method fw-compatible).
  def resolve(**)
    # `args` are the resolved arguments (Array or Hash).
    # `config` the config of the tag (containing e.g. the proc).
    block = config.fetch(:block, :itself.to_proc)
    args.join.tr(chars.join, chars.rotate(n).join).then(&block)
  end

  # Just some helper method with all characters that can be rotated.
  def chars
    %w(a b c) # etc
  end
end

Direct Known Subclasses

EnvTag, PathRootTag

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resolvable

#deep_resolve, #resolve_nested!, #try_resolve

Instance Attribute Details

#coderObject (readonly)

Returns the value of attribute coder.



191
192
193
# File 'lib/nero.rb', line 191

def coder
  @coder
end

#ctxObject (readonly)

Returns the value of attribute ctx.



191
192
193
# File 'lib/nero.rb', line 191

def ctx
  @ctx
end

#optionsObject (readonly)

Returns the value of attribute options.



191
192
193
# File 'lib/nero.rb', line 191

def options
  @options
end

Class Method Details

.[](**options) ⇒ Object

Convenience method simplifying Configuration#add_tag:

  config.add_tag("foo", klass: SomeTag[some_option: 1])


198
199
200
# File 'lib/nero.rb', line 198

def self.[](**options)
  [self, options]
end

Instance Method Details

#argsObject



224
225
226
227
228
229
230
231
232
233
# File 'lib/nero.rb', line 224

def args
  @args ||= begin
    resolve_nested!(coder)
    case coder.type
    when :map then Util.deep_symbolize_keys(coder.map)
    else
      Array(coder.public_send(coder.type))
    end
  end
end

#configObject



235
236
237
# File 'lib/nero.rb', line 235

def config
  ctx.dig(:tags, tag_name)
end

#init(ctx:, options:) ⇒ Object



207
208
209
210
# File 'lib/nero.rb', line 207

def init(ctx:, options:)
  init_ctx(ctx)
  init_options(**options)
end

#init_ctx(ctx) ⇒ Object



212
213
214
# File 'lib/nero.rb', line 212

def init_ctx(ctx)
  @ctx = ctx
end

#init_options(**options) ⇒ Object



216
217
218
# File 'lib/nero.rb', line 216

def init_options(**options)
  @options = options
end

#resolveObject



239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/nero.rb', line 239

def resolve(**)
  if (block = config[:block])
    if block.parameters.map(&:last).include?(:coder)
      # legacy
      block.call(coder, ctx)
    else
      block.call(self)
    end
  else
    args
  end
end

#tag_nameObject



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

def tag_name
  coder.tag[1..]
end