2006/5/26, Victor Shepelev <vshepelev / imho.com.ua>:

> > > The point was to do things like this:
> > >
> > > def filter(object, op, criteria)
> > >   object.send op, criteria
> > > end
> > >
> > > filter 'a', :==, 'b'
> > > filter 'Ruby', :include?, 'Ru'
> > > filter 110, :<, 15
> > >
> > > #filter 'a', :!=, 'b' <== doesn't work! :(
> >
> > Ok, I see.
> >
> > Probably, its because you are showing us a small piece of a larger puzzle,
> > but
> > why not have filter take a block:
> >
> >   def filter(object, op, criteria)
> >      yield object, criteria
> >   end
> >   filter('a', 'b') { |o,c| o != c }
> >
> > or even a proc:
> >
> >   def filter(object, op, criteria)
> >      op.call(object, criteria)
> >   end
> >   filter('a', Proc.new{ |o,c| o != c }, 'b')
>
> OK, some more pieces of puzzle :)
>
> 1. really, the former is used as bunch of filters:
>
> Request.filter [
>   [:base_type, :==, 'cpu'],
>   [:fullname, :include?, 'Intel'],
>   [:frequency, :>, 2300]
> ]
>
> 2. I'm planning inside Request to do the following:
> a) search some pre-fetched array (through Array#select)
> b) so some additional request to database
>
> For (a), filter as lambda is good; but for (b), I need some format I can
> convert into plain SQL.

This solution is not very nice, but the usage of != as symbol in
awkward anyway, the only way I got it to work is this:

irb(main):036:0> :'!='
=> :"!="

module Enumerable
  def filter(criteria)
    select do |x|
      criteria.all? do |member, op, value|
        if op == "!="
          x.send(member) != value
        else
          x.send(member).send(op, value)
        end
      end
    end
  end
end

irb(main):024:0> St = Struct.new :name, :size
=> St
irb(main):025:0> a=[St.new("foo", 10), St.new("bar", -20)]
=> [#<struct St name="foo", size=10>, #<struct St name="bar", size=-20>]
irb(main):026:0> a.filter [ [:name , "!=" , "foo"], [:size , :< , 0] ]
=> [#<struct St name="bar", size=-20>]
irb(main):027:0> a.filter [ [:name , "!=" , "foo"], [:size , :> , 0] ]
=> []

> Strange things, right? :)

No, IMHO that's a perfectly valid requirement.

Kind regards

robert

-- 
Have a look: http://www.flickr.com/photos/fussel-foto/