class Puppet::Pops::Evaluator::CompareOperator

Compares the puppet DSL way

Equality

All string vs. numeric equalities check for numeric equality first, then string equality Arrays are equal to arrays if they have the same length, and each element equals Hashes are equal to hashes if they have the same size and keys and values equals. All other objects are equal if they are ruby #== equal

Public Class Methods

new() click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
19 def initialize
20   @@equals_visitor  ||= Visitor.new(self, "equals", 1, 1)
21   @@compare_visitor ||= Visitor.new(self, "cmp", 1, 1)
22   @@match_visitor ||= Visitor.new(self, "match", 2, 2)
23   @@include_visitor ||= Visitor.new(self, "include", 2, 2)
24 end

Public Instance Methods

compare(a, b) click to toggle source

Performs a comparison of a and b, and return > 0 if a is bigger, 0 if equal, and < 0 if b is bigger. Comparison of String vs. Numeric always compares using numeric.

   # File lib/puppet/pops/evaluator/compare_operator.rb
32 def compare(a, b)
33   @@compare_visitor.visit_this_1(self, a, b)
34 end
equals(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
26 def equals(a, b)
27   @@equals_visitor.visit_this_1(self, a, b)
28 end
include?(a, b, scope) click to toggle source

Answers is b included in a

   # File lib/puppet/pops/evaluator/compare_operator.rb
42 def include?(a, b, scope)
43   @@include_visitor.visit_this_2(self, a, b, scope)
44 end
match(a, b, scope = nil) click to toggle source

Performs a match of a and b, and returns true if b matches a

   # File lib/puppet/pops/evaluator/compare_operator.rb
37 def match(a, b, scope = nil)
38   @@match_visitor.visit_this_2(self, b, a, scope)
39 end

Protected Instance Methods

cmp_Numeric(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
59 def cmp_Numeric(a, b)
60   if b.is_a?(Numeric)
61     a <=> b
62   elsif b.is_a?(Time::Timespan) || b.is_a?(Time::Timestamp)
63     -(b <=> a) # compare other way and invert result
64   else
65     raise ArgumentError.new(_("A Numeric is not comparable to non Numeric"))
66   end
67 end
cmp_Object(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
112 def cmp_Object(a, b)
113   raise ArgumentError.new(_('Only Strings, Numbers, Timespans, Timestamps, and Versions are comparable'))
114 end
cmp_String(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
48 def cmp_String(a, b)
49   return a.casecmp(b) if b.is_a?(String)
50   raise ArgumentError.new(_("A String is not comparable to a non String"))
51 end
cmp_Symbol(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
89 def cmp_Symbol(a, b)
90   if b.is_a?(Symbol)
91     a <=> b
92   else
93     raise ArgumentError.new(_("Symbol not comparable to non Symbol"))
94   end
95 end
cmp_Timespan(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
 97 def cmp_Timespan(a, b)
 98   raise ArgumentError.new(_('Timespans are only comparable to Timespans, Integers, and Floats')) unless b.is_a?(Time::Timespan) ||  b.is_a?(Integer) || b.is_a?(Float)
 99   a <=> b
100 end
cmp_Timestamp(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
102 def cmp_Timestamp(a, b)
103   raise ArgumentError.new(_('Timestamps are only comparable to Timestamps, Integers, and Floats')) unless b.is_a?(Time::Timestamp) ||  b.is_a?(Integer) || b.is_a?(Float)
104   a <=> b
105 end
cmp_Version(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
107 def cmp_Version(a, b)
108   raise ArgumentError.new(_('Versions not comparable to non Versions')) unless b.is_a?(SemanticPuppet::Version)
109   a <=> b
110 end
equals_Array(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
77 def equals_Array(a, b)
78   return false unless b.is_a?(Array) && a.size == b.size
79   a.each_index {|i| return false unless equals(a.slice(i), b.slice(i)) }
80   true
81 end
equals_Hash(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
83 def equals_Hash(a, b)
84   return false unless b.is_a?(Hash) && a.size == b.size
85   a.each {|ak, av| return false unless equals(b[ak], av)}
86   true
87 end
equals_NilClass(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
121 def equals_NilClass(a, b)
122   # :undef supported in case it is passed from a 3x data structure
123   b.nil? || b == :undef
124 end
equals_Numeric(a, b) click to toggle source
   # File lib/puppet/pops/evaluator/compare_operator.rb
69 def equals_Numeric(a, b)
70   if b.is_a?(Numeric)
71     a == b
72   else
73     false
74   end
75 end
equals_Object(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
117 def equals_Object(a, b)
118   a == b
119 end
equals_String(a, b) click to toggle source

Equality is case independent.

   # File lib/puppet/pops/evaluator/compare_operator.rb
54 def equals_String(a, b)
55   return false unless b.is_a?(String)
56   a.casecmp(b) == 0
57 end
equals_Symbol(a, b) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
126 def equals_Symbol(a, b)
127   # :undef supported in case it is passed from a 3x data structure
128   a == b || a == :undef && b.nil?
129 end
include_Array(a, b, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
165 def include_Array(a, b, scope)
166   case b
167   when Regexp
168     matched = nil
169     a.each do |element|
170       next unless element.is_a? String
171       matched = element.match(b) # nil, or MatchData
172       break if matched
173     end
174     # Always set match data, a "not found" should not keep old match data visible
175     set_match_data(matched, scope) # creates ephemeral
176     return !!matched
177   when String, SemanticPuppet::Version
178     a.any? { |element| match(b, element, scope) }
179   when Types::PAnyType
180     a.each {|element| return true if b.instance?(element) }
181     return false
182   else
183     a.each {|element| return true if equals(element, b) }
184     return false
185   end
186 end
include_Binary(a, b, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
152 def include_Binary(a, b, scope)
153   case b
154   when Puppet::Pops::Types::PBinaryType::Binary
155     a.binary_buffer.include?(b.binary_buffer)
156   when String
157     a.binary_buffer.include?(b)
158   when Numeric
159     a.binary_buffer.bytes.include?(b)
160   else
161     false
162   end
163 end
include_Hash(a, b, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
188 def include_Hash(a, b, scope)
189   include?(a.keys, b, scope)
190 end
include_Object(a, b, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
131 def include_Object(a, b, scope)
132   false
133 end
include_String(a, b, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
135 def include_String(a, b, scope)
136   case b
137   when String
138     # substring search downcased
139     a.downcase.include?(b.downcase)
140   when Regexp
141     matched = a.match(b)           # nil, or MatchData
142     set_match_data(matched, scope) # creates ephemeral
143     !!matched                      # match (convert to boolean)
144   when Numeric
145     # convert string to number, true if ==
146     equals(a, b)
147   else
148     false
149   end
150 end
include_VersionRange(a, b, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
192 def include_VersionRange(a, b, scope)
193   Types::PSemVerRangeType.include?(a, b)
194 end
match_Array(array, left, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
237 def match_Array(array, left, scope)
238   return false unless left.is_a?(Array)
239   return false unless left.length == array.length
240   array.each_with_index.all? { | pattern, index| match(left[index], pattern, scope) }
241 end
match_Hash(hash, left, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
243 def match_Hash(hash, left, scope)
244   return false unless left.is_a?(Hash)
245   hash.all? {|x,y| match(left[x], y, scope) }
246 end
match_Object(pattern, a, scope) click to toggle source

Matches in general by using == operator

    # File lib/puppet/pops/evaluator/compare_operator.rb
197 def match_Object(pattern, a, scope)
198   equals(a, pattern)
199 end
match_PAnyType(any_type, left, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
229 def match_PAnyType(any_type, left, scope)
230   # right is a type and left is not - check if left is an instance of the given type
231   # (The reverse is not terribly meaningful - computing which of the case options that first produces
232   # an instance of a given type).
233   #
234   any_type.instance?(left)
235 end
match_Regexp(regexp, left, scope) click to toggle source

Matches only against strings

    # File lib/puppet/pops/evaluator/compare_operator.rb
202 def match_Regexp(regexp, left, scope)
203   return false unless left.is_a? String
204   matched = regexp.match(left)
205   set_match_data(matched, scope) unless scope.nil? # creates or clears ephemeral
206   !!matched # convert to boolean
207 end
match_Symbol(symbol, left, scope) click to toggle source
    # File lib/puppet/pops/evaluator/compare_operator.rb
248 def match_Symbol(symbol, left, scope)
249   return true if symbol == :default
250   equals(left, default)
251 end
match_Version(version, left, scope) click to toggle source

Matches against semvers and strings

    # File lib/puppet/pops/evaluator/compare_operator.rb
210 def match_Version(version, left, scope)
211   if left.is_a?(SemanticPuppet::Version)
212     version == left
213   elsif left.is_a? String
214     begin
215       version == SemanticPuppet::Version.parse(left)
216     rescue ArgumentError
217       false
218     end
219   else
220     false
221   end
222 end
match_VersionRange(range, left, scope) click to toggle source

Matches against semvers and strings

    # File lib/puppet/pops/evaluator/compare_operator.rb
225 def match_VersionRange(range, left, scope)
226   Types::PSemVerRangeType.include?(range, left)
227 end