Class: TaskJuggler::LogicalOperation

Inherits:
Object
  • Object
show all
Defined in:
lib/taskjuggler/LogicalOperation.rb

Overview

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.

Direct Known Subclasses

LogicalAttribute, LogicalFlag

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opnd1, operator = nil, opnd2 = nil) ⇒ LogicalOperation

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



35
36
37
38
39
# File 'lib/taskjuggler/LogicalOperation.rb', line 35

def initialize(opnd1, operator = nil, opnd2 = nil)
  @operand1 = opnd1
  @operand2 = opnd2
  @operator = operator
end

Instance Attribute Details

#operand1Object (readonly)

Returns the value of attribute operand1.



30
31
32
# File 'lib/taskjuggler/LogicalOperation.rb', line 30

def operand1
  @operand1
end

#operand2Object

Returns the value of attribute operand2.



31
32
33
# File 'lib/taskjuggler/LogicalOperation.rb', line 31

def operand2
  @operand2
end

#operatorObject

Returns the value of attribute operator.



31
32
33
# File 'lib/taskjuggler/LogicalOperation.rb', line 31

def operator
  @operator
end

Instance Method Details

#eval(expr) ⇒ Object

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.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/taskjuggler/LogicalOperation.rb', line 44

def eval(expr)
  case @operator
  when nil
    if @operand1.respond_to?(:eval)
      # An operand can be a fixed value or another term. This could be a
      # LogicalOperation, LogicalFunction or anything else that provides
      # an appropriate eval() method.
      return @operand1.eval(expr)
    else
      return @operand1
    end
  when '~'
    return !coerceBoolean(@operand1.eval(expr), expr)
  when '>', '>=', '=', '<', '<=', '!='
    # Evaluate the operation for all 2 operand operations that can be
    # either interpreted as date, numbers or Strings.
    opnd1 = @operand1.eval(expr)
    opnd2 = @operand2.eval(expr)
    if opnd1.is_a?(TjTime)
      res= evalBinaryOperation(opnd1, operator, opnd2) do |o|
        coerceTime(o, expr)
      end
      return res
    elsif opnd1.is_a?(Integer) || opnd1.is_a?(Float)
      return evalBinaryOperation(opnd1, operator, opnd2) do |o|
        coerceNumber(o, expr)
      end
    elsif opnd1.is_a?(RichTextIntermediate)
      return evalBinaryOperation(opnd1.to_s, operator, opnd2) do |o|
        coerceString(o, expr)
      end
    elsif opnd1.is_a?(String)
      return evalBinaryOperation(opnd1, operator, opnd2) do |o|
        coerceString(o, expr)
      end
    else
      expr.error("First operand of a binary operation must be a date, " +
                 "a number or a string: #{opnd1.class}")
    end
  when '&'
    return coerceBoolean(@operand1.eval(expr), expr) &&
           coerceBoolean(@operand2.eval(expr), expr)
  when '|'
    return coerceBoolean(@operand1.eval(expr), expr) ||
           coerceBoolean(@operand2.eval(expr), expr)
  else
    expr.error("Unknown operator #{@operator} in logical expression")
  end
end

#to_s(query) ⇒ Object

Convert the operation into a textual representation.



95
96
97
98
99
100
101
102
103
104
# File 'lib/taskjuggler/LogicalOperation.rb', line 95

def to_s(query)
  if @operator.nil?
    operand_to_s(@operand1, query)
  elsif @operand2.nil?
    @operator + operand_to_s(@operand1, query)
  else
    "(#{operand_to_s(@operand1, query)} #{@operator} " +
    "#{operand_to_s(@operand2, query)})"
  end
end