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+)\)$/.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAttributeResolver

Returns a new instance of AttributeResolver


16
17
18
# File 'lib/attributor/attribute_resolver.rb', line 16

def initialize
  @data = Data.new
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data


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

def data
  @data
end

Class Method Details

.currentObject


115
116
117
118
119
120
121
# File 'lib/attributor/attribute_resolver.rb', line 115

def self.current
  if resolver = Thread.current[:_attributor_attribute_resolver]
    return resolver
  else
    raise AttributorException, "No AttributeResolver set."
  end
end

.current=(resolver) ⇒ Object

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


110
111
112
# File 'lib/attributor/attribute_resolver.rb', line 110

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:


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/attributor/attribute_resolver.rb', line 87

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

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

  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.new("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


60
61
62
63
64
# File 'lib/attributor/attribute_resolver.rb', line 60

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

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


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
48
49
50
# File 'lib/attributor/attribute_resolver.rb', line 21

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


66
67
68
69
70
71
72
# File 'lib/attributor/attribute_resolver.rb', line 66

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

  @data[key_path] = value
end