"Florian Weber" <csshsh / structbench.com> schrieb im Newsbeitrag
news:D83A07D2-AE5C-11D8-A68B-000A95BD142E / structbench.com...
> hi!
>
> im trying to define a set of rules with ruby, however i cant find a more
> ruby-like way to do so..
>
> instead of doing something like
>
> my_set.add(NotNamedRule("orange").new)
> my_set.add(HasPropertyRule("color").new)
> my_set.add(OrRule(HasPropertyRule("size").new,
> HasPropertyRule("weight").new))
>
> (i know this is a horrible example. excuse the awful 'design'. its
> justs to illustrate
> what i not wanna have ; )
>
> i wanna do something like
>
> my_set.rules = !name("orange") && hasProperty("color") &&
> (hasProperty("size") || hasProperty("weight"))

You won't be able to make this work as rule creation because of short
circuit evaluation of '&&' and '||'.

> can anybody think of a nice way to do this?

You could do:

#!/#!/usr/bin/ruby

module Rule
  def self.create(&b)
    def b.===(obj)
      call obj
    end
    b
  end

  def self.and(*rules)
    def rules.===(obj)
      all? {|r| r === obj}
    end
    rules
  end

  def self.or(*rules)
    def rules.===(obj)
      any? {|r| r === obj}
    end
    rules
  end
end

r1 = Rule.create {|o| o.name != "orange" && o.color && (o.size ||
o.weight) }
r2 = Rule.create {|o| o.name == "orange" && o.color && (o.size ||
o.weight) }

require 'ostruct'
obj = OpenStruct.new
obj.name = "green"
obj.color = "yellow"
obj.size = 10

p r1 === obj
p Rule.and( r1, r2 ) === obj
p Rule.or( r1, r2 ) === obj

R#!/usr/bin/ruby

module Rule
  def self.create(&b)
    def b.===(obj)
      call obj
    end
    b
  end

  def self.and(*rules)
    def rules.===(obj)
      all? {|r| r === obj}
    end
    rules
  end

  def self.or(*rules)
    def rules.===(obj)
      any? {|r| r === obj}
    end
    rules
  end
end

r1 = Rule.create {|o| o.name != "orange" && o.color && (o.size ||
o.weight) }
r2 = Rule.create {|o| o.name == "orange" && o.color && (o.size ||
o.weight) }

# testing...
require 'ostruct'
obj = OpenStruct.new
obj.name = "green"
obj.color = "yellow"
obj.size = 10

p r1 === obj
p Rule.and( r1, r2 ) === obj
p Rule.or( r1, r2 ) === obj

Regards

    robert