Robert Klemme <bob.news / gmx.net> wrote:

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