Ruleby / ruleby

the Rules Engine for Ruby
http://www.ruleby.org
Other
327 stars 42 forks source link

bound variable unavailable to condition clause. #14

Open robblovell opened 14 years ago

robblovell commented 14 years ago

In this simple example, the condition clause doesn't seem to be able to reference a bound variable from a previous part of the clause:

# 
# Example of situation where bound variable is not available to the condition clause.
#

$LOAD_PATH << File.join(File.dirname(__FILE__), '../lib/')
require 'ruleby'

include Ruleby

class Q
  def initialize(status,message,value)
    @status = status
    @message = message
    @value = value
  end
  attr :status, true
  attr :message, true
  attr :value, true
end

class HelloWorldRulebook < Rulebook
  def rules
=begin
    # original rule
    rule [Q, :p, {m.value=>:pv}, m.status == :HELLO],
         [Q, :q, m.status == :GOODBYE,m.value == b(:pv)]  do |v|
      puts v[:p].message + " " +v[:q].message
    end
=end
    # the next two rules should be equivalent to the original rule but are not.
    rule [Q, :p, {m.value=>:pv}, m.status == :HELLO],
         [Q, :q, m.status == :GOODBYE,m.value(&condition{|c| c == b(:pv)})]  do |v|
      puts v[:p].message + " " +v[:q].message
    end
    rule [Q, :p, {m.value=>:pv}, m.status == :HELLO],
         [Q, :q, m.status == :GOODBYE,m.value(b(:pv),&condition{|v,pv| v == pv})]  do |v|
      puts v[:p].message + " " +v[:q].message
    end

  end
end

engine :engine do |e|
  r=HelloWorldRulebook.new(e)
  r.rules
  e.assert Q.new(:HELLO, 'Hello',1)
  e.assert Q.new(:GOODBYE, 'World',1)
  e.match
end; 
drfeelngood commented 12 years ago

@robblovell Try the following syntax:

require 'ruleby'

class Q
  attr_accessor :status, :message, :value

  def initialize(status, message, value)
    @status, @message, @value = status, message, value
    puts "status[%s] message[%s] value[%d]" % [@status, @message, @value]
  end

end

class HelloWorldRulebook < Ruleby::Rulebook

  def rules

    rule [Q, :p, { m.value => :pv }, m.status == :HELLO],
         [Q, :q, m.status == :GOODBYE, m.value(:pv, &c{ |qv, pv| qv == pv })] do |v|
      puts v[:p].message + " " + v[:q].message
    end

    rule [Q, :p, { m.value => :pv }, m.status == :HELLO],
         [Q, :q, m.status == :GOODBYE,m.value(:pv, &c{ |qv, pv| qv == pv })] do |v|
      puts v[:p].message + " " + v[:q].message
    end

  end

end

include Ruleby

engine :engine do |e|
  r=HelloWorldRulebook.new(e)
  r.rules
  e.assert Q.new(:HELLO, 'Hello', 1)
  e.assert Q.new(:GOODBYE, 'World', 1)
  e.match
end

This results in:

Hello World
Hello World