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

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 serializer, 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
48
# 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
  @key_converter = key_converter
  @matchers = []
  
  if spec.respond_to? :to_hash # assume hash-like
    @shibboleth = :to_hash
    spec.each do |k, v|
      if key_converter
        k = key_converter[k => nil].keys[0]
        # 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.
      end
      fill_matchers k, 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

#key_converterObject (readonly)

Returns the value of attribute key_converter.



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

def key_converter
  @key_converter
end

#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.



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

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



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

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.



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

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