Parent

Class Index [+]

Quicksearch

TaskJuggler::LogicalOperation

A LogicalOperation is the basic building block for a LogicalExpression. A logical operation has one or two operands and an operator. The operands can be LogicalOperation objects, fixed values or references to project data. The LogicalOperation can be evaluated in a certain context. This contexts determines the actual values of the project data references. The evaluation is done by calling LogicalOperation#eval. The result must be of a type that responds to all the operators that are used in the eval method.

Attributes

operand1[R]
operand2[RW]
operator[RW]

Public Class Methods

new(opnd1, operator = nil, opnd2 = nil) click to toggle source

Create a new LogicalOperation object. opnd1 is the mandatory operand. The @operand2 and the @operator can be set later.

    # File lib/LogicalOperation.rb, line 33
33:     def initialize(opnd1, operator = nil, opnd2 = nil)
34:       @operand1 = opnd1
35:       @operand2 = opnd2
36:       @operator = operator
37:     end

Public Instance Methods

eval(expr) click to toggle source

Evaluate the expression in a given context represented by expr of type LogicalExpression. The result must be of a type that responds to all the operators of this function.

    # File lib/LogicalOperation.rb, line 42
42:     def eval(expr)
43:       case @operator
44:       when nil
45:         if @operand1.respond_to?(:eval)
46:           # An operand can be a fixed value or another term. This could be a
47:           # LogicalOperation, LogicalFunction or anything else that provides
48:           # an appropriate eval() method.
49:           return @operand1.eval(expr)
50:         else
51:           return @operand1
52:         end
53:       when '~'
54:         return !coerceBoolean(@operand1.eval(expr), expr)
55:       when '>', '>=', '=', '<', '<=', '!='
56:         # Evaluate the operation for all 2 operand operations that can be
57:         # either interpreted as date, numbers or Strings.
58:         opnd1 = @operand1.eval(expr)
59:         opnd2 = @operand2.eval(expr)
60:         if opnd1.is_a?(TjTime)
61:           res= evalBinaryOperation(opnd1, operator, opnd2) do |o|
62:             coerceTime(o, expr)
63:           end
64:           return res
65:         elsif opnd1.is_a?(Fixnum) || opnd1.is_a?(Float) || opnd1.is_a?(Bignum)
66:           return evalBinaryOperation(opnd1, operator, opnd2) do |o|
67:             coerceNumber(o, expr)
68:           end
69:         elsif opnd1.is_a?(RichTextIntermediate)
70:           return evalBinaryOperation(opnd1.to_s, operator, opnd2) do |o|
71:             coerceString(o, expr)
72:           end
73:         elsif opnd1.is_a?(String)
74:           return evalBinaryOperation(opnd1, operator, opnd2) do |o|
75:             coerceString(o, expr)
76:           end
77:         else
78:           expr.error("First operand of a binary operation must be a date, " +
79:                      "a number or a string: #{opnd1.class}")
80:         end
81:       when '&'
82:         return coerceBoolean(@operand1.eval(expr), expr) &&
83:                coerceBoolean(@operand2.eval(expr), expr)
84:       when '|'
85:         return coerceBoolean(@operand1.eval(expr), expr) ||
86:                coerceBoolean(@operand2.eval(expr), expr)
87:       else
88:         expr.error("Unknown operator #{@operator} in logical expression")
89:       end
90:     end
to_s(query) click to toggle source

Convert the operation into a textual representation.

     # File lib/LogicalOperation.rb, line 93
 93:     def to_s(query)
 94:       if @operator.nil?
 95:         operand_to_s(@operand1, query)
 96:       elsif @operand2.nil?
 97:         @operator + operand_to_s(@operand1, query)
 98:       else
 99:         "(#{operand_to_s(@operand1, query)} #{@operator} " +
100:         "#{operand_to_s(@operand2, query)})"
101:       end
102:     end

Private Instance Methods

coerceBoolean(val, expr) click to toggle source

Force the val into a boolean value.

     # File lib/LogicalOperation.rb, line 140
140:     def coerceBoolean(val, expr)
141:       # First the obvious ones.
142:       return val if val.class == TrueClass || val.class == FalseClass
143:       # An empty String means false, else true.
144:       return !val.empty? if val.is_a?(String)
145:       # In TJP logic 'non 0' means false.
146:       return val != 0 if val.is_a?(Fixnum) || val.is_a?(Bignum)
147: 
148:       expr.error("Operand #{val} can't be evaluated to true or false.")
149:     end
coerceNumber(val, expr) click to toggle source

Force the val into a number. In case this fails, an exception is raised.

     # File lib/LogicalOperation.rb, line 152
152:     def coerceNumber(val, expr)
153:       unless val.is_a?(Fixnum) || val.is_a?(Float) || val.is_a?(Bignum)
154:         expr.error("Operand #{val} of type #{val.class} must be a number.")
155:       end
156:       val
157:     end
coerceString(val, expr) click to toggle source

Force the val into a String. In case this fails, an exception is raised.

     # File lib/LogicalOperation.rb, line 160
160:     def coerceString(val, expr)
161:       unless val.respond_to?('to_s')
162:         expr.error("Operand #{val} of type #{val.class} can't be converted " +
163:                    "into a string")
164:       end
165:       val
166:     end
coerceTime(val, expr) click to toggle source

Force the val into a String. In case this fails, an exception is raised.

     # File lib/LogicalOperation.rb, line 169
169:     def coerceTime(val, expr)
170:       unless val.is_a?(TjTime)
171:         expr.error("Operand #{val} of type #{val.class} can't be converted " +
172:                    "into a date")
173:       end
174:       val
175:     end
evalBinaryOperation(opnd1, operator, opnd2) click to toggle source

We need to do binary operator evaluation with various coerce functions. This function does the evaluation of opnd1 and opnd2 with the operation specified by operator. The operands are first coerced into the proper format by calling the block.

     # File lib/LogicalOperation.rb, line 120
120:     def evalBinaryOperation(opnd1, operator, opnd2)
121:       case operator
122:       when '>'
123:         return yield(opnd1) > yield(opnd2)
124:       when '>='
125:         return yield(opnd1) >= yield(opnd2)
126:       when '='
127:         return yield(opnd1) == yield(opnd2)
128:       when '<'
129:         return yield(opnd1) < yield(opnd2)
130:       when '<='
131:         return yield(opnd1) <= yield(opnd2)
132:       when '!='
133:         return yield(opnd1) != yield(opnd2)
134:       else
135:         raise "Operator error"
136:       end
137:     end
operand_to_s(operand, query) click to toggle source
     # File lib/LogicalOperation.rb, line 106
106:     def operand_to_s(operand, query)
107:       if operand.is_a?(LogicalOperation)
108:         operand.to_s(query)
109:       elsif operand.is_a?(String)
110:         "'#{operand}'"
111:       else
112:         operand.to_s
113:       end
114:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.