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.2"

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.



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
# File 'lib/object-template.rb', line 18

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]: k
        # Note: cannot use key_converter[v] because v may have class, regex,
        # or other non-serializable object.
      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 Method Details

#===(obj) ⇒ Object

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



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/object-template.rb', line 64

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



81
82
83
# File 'lib/object-template.rb', line 81

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.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/object-template.rb', line 47

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