"Simon Strandgaard" <0bz63fz3m1qt3001 / sneakemail.com> schrieb im
Newsbeitrag news:pan.2003.07.21.12.42.13.887241 / sneakemail.com...

> OK.. this is the nicest solution so far :-)

I've found an even nicer solution that allows user defined comparisons
nicely:

def less(*args); check_chain(*args){|a,b|a<b}; end
def greater(*args); check_chain(*args){|a,b|a>b}; end

def check_chain(*args, &comp)
  raise "Block needed" unless comp

  last = nil

  args.each do |i|
    return false if last and not comp.call(last,i)
    last = i
  end

  true
end

less 1,10,22
less 2,1,14
less -2,1,14
greater 10,3,-100
greater 2,1,14

check_chain( 2, 4, 16 ){|a,b| a*a==b}
check_chain( 2, 4, 17 ){|a,b| a*a==b}

The thing that bugged my about the last one was the first parameter to
compare_chain() which prevented nice user defined checks.

> I didn't thought of using proc's for binary compares.

The proposed implementation of ordering? inspired my.  Though while
writing this I see a more general pattern here that reminds a bit of
Enumerable#inject (Ruby 1.8):

module Enumerable
  def connect(coll)
    last = nil
    first = true

    each do |i|
      if first
        first = false
      else
        coll = yield(coll,last,i)
      end

      last = i
    end

    coll
  end
end

def less(*args); args.connect( true ){|c,a,b|c && a<b}; end
def greater(*args); args.connect( true ){|c,a,b|c && a>b}; end

[1, 2, 3].connect( true ){|coll,a,b|coll && a<b}
[2, 4, 16].connect( true ){|coll,a,b|coll && a*a==b}

These versions are less efficient for sequences that fail the test but one
might consider to change the implementation to stop if coll is false or
nil.

Method Enumerable#connect might even be considert a library addenum, IMHO.
Maybe inject might be changed to yield one more parameter the way it is
shown here.  What does Matz think?  What do others think?

Regards

    robert