Class: ObjectTemplate

Inherits:
Object
  • Object
show all
Defined in:
lib/object-template.rb

Overview

Base class for classes of templates used to match somewhat arbitrary objects.

Direct Known Subclasses

PortableObjectTemplate, RubyObjectTemplate

Defined Under Namespace

Classes: MemberMatchingSet

Constant Summary collapse

VERSION =
"0.7"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(spec, key_converter = nil) ⇒ ObjectTemplate

The key_converter is for matching objects that, for example, have had symbol keys serialized to strings. Using a converter that round-trips through the same serialializer, symbols in keys will match strings. However, symbols in values will not.



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/object-template.rb', line 20

def initialize spec, key_converter = nil
  unless spec.respond_to? :size and spec.respond_to? :each
    raise ArgumentError, "cannot be used as a template: #{spec.inspect}"
  end

  @spec = spec
  @size = spec.size
  @matchers = []
  
  if spec.respond_to? :to_hash # assume hash-like
    @shibboleth = :to_hash
    spec.each do |k, v|
      kc = key_converter ? key_converter[k=>nil].keys[0] : k
        # Note: cannot use key_converter[v] because v may have class, regex,
        # or other non-serializable object.
        # Note: the [k=>nil].keys[0] is needed instead of just [k]
        # because the key_converter might not convert values, only keys.
        # We do not assume that k is a scalar.
      fill_matchers kc, v
    end

  else # assume array-like
    @shibboleth = :to_ary
    spec.each_with_index do |v, i|
      fill_matchers i, v unless v.nil?
    end
  end
end

Instance Attribute Details

#specObject (readonly)

Returns the value of attribute spec.



7
8
9
# File 'lib/object-template.rb', line 7

def spec
  @spec
end

Instance Method Details

#===(obj) ⇒ Object

True if the template matches the given object. Adapted from rinda/rinda.rb.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/object-template.rb', line 69

def === obj
  return false unless obj.respond_to?(@shibboleth)
  return false unless @size == obj.size
  @matchers.each do |k, v|
    begin
      it = obj.fetch(k)
    rescue
      return false
    end
    next if v.nil?
    next if v == it
    next if v === it
    return false
  end
  return true
end

#inspectObject



86
87
88
# File 'lib/object-template.rb', line 86

def inspect
  "<#{self.class}: #{@spec}>"
end

#optimize!Object

Reorders the list of matchers so that easy ones come first. For example: nil, then single values (==), then patterns (===). Returns self.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/object-template.rb', line 52

def optimize!
  @matchers.sort_by! do |k, v|
    case v
    when nil;               0
    when Range;             2
    when Module;            3
    when Regexp;            4
    when MemberMatchingSet; 4
    when Proc;              5
    else                    1 # assume it is a value
    end
  end
  self
end