Class: Attributor::AttributeResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/attributor/attribute_resolver.rb

Defined Under Namespace

Classes: Data

Constant Summary collapse

ROOT_PREFIX =
'$'.freeze
COLLECTION_INDEX_KEY =
/^at\((\d+)\)$/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAttributeResolver

Returns a new instance of AttributeResolver.



14
15
16
# File 'lib/attributor/attribute_resolver.rb', line 14

def initialize
  @data = Data.new
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



12
13
14
# File 'lib/attributor/attribute_resolver.rb', line 12

def data
  @data
end

Class Method Details

.currentObject



106
107
108
109
# File 'lib/attributor/attribute_resolver.rb', line 106

def self.current
  raise AttributorException, 'No AttributeResolver set.' unless Thread.current[:_attributor_attribute_resolver]
  Thread.current[:_attributor_attribute_resolver]
end

.current=(resolver) ⇒ Object

TODO: kill this when we also kill Taylor’s IdentityMap.current



102
103
104
# File 'lib/attributor/attribute_resolver.rb', line 102

def self.current=(resolver)
  Thread.current[:_attributor_attribute_resolver] = resolver
end

Instance Method Details

#check(path_prefix, key_path, predicate = nil) ⇒ Object

Checks that the the condition is met. This means the attribute identified by path_prefix and key_path satisfies the optional predicate, which when nil simply checks for existence.

Parameters:

Raises:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/attributor/attribute_resolver.rb', line 82

def check(path_prefix, key_path, predicate = nil)
  value = query(key_path, path_prefix)

  # we have a value, any value, which is good enough given no predicate
  return true if !value.nil? && predicate.nil?

  case predicate
  when ::String, ::Regexp, ::Integer, ::Float, ::DateTime, true, false
    return predicate === value
  when ::Proc
    # Cannot use === here as above due to different behavior in Ruby 1.8
    return predicate.call(value)
  when nil
    return !value.nil?
  else
    raise AttributorException, "predicate not supported: #{predicate.inspect}"
  end
end

#query(key_path, path_prefix = ROOT_PREFIX) ⇒ String

Query for a certain key in the attribute hierarchy

Parameters:

  • key_path (String)

    The name of the key to query and its path

  • path_prefix (String) (defaults to: ROOT_PREFIX)

Returns:

  • (String)

    The value of the specified attribute/key



56
57
58
59
60
# File 'lib/attributor/attribute_resolver.rb', line 56

def query(key_path, path_prefix = ROOT_PREFIX)
  query!(key_path, path_prefix)
rescue NoMethodError
  nil
end

#query!(key_path, path_prefix = ROOT_PREFIX) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/attributor/attribute_resolver.rb', line 18

def query!(key_path, path_prefix = ROOT_PREFIX)
  # If the incoming key_path is not an absolute path, append the given prefix
  # NOTE: Need to index key_path by range here because Ruby 1.8 returns a
  # FixNum for the ASCII code, not the actual character, when indexing by a number.
  unless key_path[0..0] == ROOT_PREFIX
    # TODO: prepend path_prefix to path_prefix if it did not include it? hm.
    key_path = path_prefix + SEPARATOR + key_path
  end

  # Discard the initial element, which should always be ROOT_PREFIX at this point
  _root, *path = key_path.split(SEPARATOR)

  # Follow the hierarchy path to the requested node and return it:
  # Example path => ["instance", "ssh_key", "name"]
  # Example @data => {"instance" => { "ssh_key" => { "name" => "foobar" } }}
  #
  # at(n) is a collection index:
  # Example path => ["filters", "at(0)", "type"]
  # Example data => {"filters" => [{ "type" => "instance:tag" }]}
  #
  result = path.inject(@data) do |hash, key|
    return nil if hash.nil?
    if (match = key.match(COLLECTION_INDEX_KEY))
      hash[match[1].to_i]
    else
      hash.send key
    end
  end
  result
end

#register(key_path, value) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/attributor/attribute_resolver.rb', line 62

def register(key_path, value)
  if key_path.split(SEPARATOR).size > 1
    raise AttributorException, "can only register top-level attributes. got: #{key_path}"
  end

  @data[key_path] = value
end