File: complex.rb

package info (click to toggle)
ruby-god 0.13.7-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 832 kB
  • sloc: ruby: 6,641; ansic: 237; makefile: 3
file content (86 lines) | stat: -rw-r--r-- 1,933 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
module God
  module Conditions

    class Complex < PollCondition
      AND = 0x1
      OR  = 0x2
      NOT = 0x4

      def initialize()
        super

        @oper_stack = []
        @op_stack = []

        @this = nil
      end

      def valid?
        @oper_stack.inject(true) { |acc, oper| acc & oper.valid? }
      end

      def prepare
        @oper_stack.each { |oper| oper.prepare }
      end

      def new_oper(kind, op)
        oper = Condition.generate(kind, self.watch)
        @oper_stack.push(oper)
        @op_stack.push(op)
        oper
      end

      def this(kind)
        @this = Condition.generate(kind, self.watch)
        yield @this if block_given?
      end

      def and(kind)
        oper = new_oper(kind, 0x1)
        yield oper if block_given?
      end

      def and_not(kind)
        oper = new_oper(kind, 0x5)
        yield oper if block_given?
      end

      def or(kind)
        oper = new_oper(kind, 0x2)
        yield oper if block_given?
      end

      def or_not(kind)
        oper = new_oper(kind, 0x6)
        yield oper if block_given?
      end

      def test
        if @this.nil?
          # Although this() makes sense semantically and therefore
          # encourages easy-to-read conditions, being able to omit it
          # allows for more DRY code in some cases, so we deal with a
          # nil @this here by initially setting res to true or false,
          # depending on whether the first operator used is AND or OR
          # respectively.
          if 0 < @op_stack[0] & AND
            res = true
          else
            res = false
          end
        else
          res = @this.test
        end

        @op_stack.each do |op|
          cond = @oper_stack.shift
          eval "res " + ((0 < op & AND) ? "&&" : "||") + "= " + ((0 < op & NOT) ? "!" : "") + "cond.test"
          @oper_stack.push cond
        end

        res
      end
    end

  end
end