An easy way around it is to use ('a'..'z').entries.include?(1)
instead
That does not work when Range#start is a Float (and it builds an
additional Array)
Also, there are several equally valid interpretations of Range#include?:
(a)
- True, if the range while iterating yields the specific value (std
definition from Enumerable)
(b)
- True, if low <= x <= high
(c)
- True, if low < x <= high
Interesting. I would lean towards (b) (which I believe is the current implementation if exclude_end? is false).
(a) is not really practical because Range is not always Enumerable and this also conflicts with my mental model of a "Range"
So maybe Range#include? is not that useful after all... Or we should
leave the std definition from Enumerable in place and introduce
Range#contains? or Range#covers? to deal with the more range specific
interpretations.
A little more context on what I was trying to do:
I'm writing a class to filter bytestreams according to various parameters.
class Filter
attr_accessor :pattern, :expr
def initialize(expr=nil, pattern=nil)
@expr = expr ||
@pattern = pattern || "C*"
end
def include?(data)
ary = data.to_str.unpack(@pattern)
@expr.zip(ary).each { |e,a|
if e.respond_to?(:include?)
return false unless e.include?(a)
else
return false unless e === a
end
}
return true
rescue ArgumentError, TypeError
# if data does not fit @pattern
return false
end
end
end
The Bytestream is unpacked and then matched to a given Expression.
A few examples:
Filter.new([?A,?B]).include?("ABCDEF") #=> true
Filter.new([?A,?B]).include?("CDEF") #=> false
Filter.new(["AaBb"]).include?("afoo") #=> true
Filter.new([/^foo/],"a*").include?("foobar") #=> true
Filter.new([/^foo/],"a*").include?("barfoo") #=> false
Filter.new([?a..?z]).include?("afoo") #=> true
Filter.new(["a".."z"]).include?("c") #=> NoMethodError [1]
[1] but should return false, because '("a".."c").include?(?a)'
should imho return false to be consistent with ["a","b","c"].include?(?a)
-Levin
···
Robert Klemme <bob.news@gmx.net> wrote: