bali 2.4.0 → 6.0.0rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -13
- data/.rspec +1 -0
- data/lib/bali.rb +23 -14
- data/lib/bali/activerecord.rb +8 -0
- data/lib/bali/authorizer.rb +24 -0
- data/lib/bali/config.rb +12 -0
- data/lib/bali/dsl_error.rb +3 -0
- data/lib/bali/{foundations/exceptions/bali_error.rb → error.rb} +0 -0
- data/lib/bali/judge.rb +239 -0
- data/lib/bali/printer.rb +16 -26
- data/lib/bali/railtie.rb +13 -0
- data/lib/bali/role.rb +79 -0
- data/lib/bali/rule.rb +17 -0
- data/lib/bali/ruler.rb +36 -0
- data/lib/bali/rules.rb +68 -0
- data/lib/bali/tasks/bali/print_rules.rake +9 -0
- data/lib/bali/version.rb +1 -1
- data/lib/generators/rails/USAGE +8 -0
- data/lib/generators/rails/rules_generator.rb +17 -0
- data/lib/generators/rails/templates/rules.rb +4 -0
- data/lib/generators/rspec/rules_generator.rb +12 -0
- data/lib/generators/rspec/templates/rules_spec.rb +7 -0
- metadata +104 -47
- data/lib/bali/dsl/map_rules_dsl.rb +0 -75
- data/lib/bali/dsl/rules_for_dsl.rb +0 -130
- data/lib/bali/foundations/all_foundations.rb +0 -17
- data/lib/bali/foundations/exceptions/authorization_error.rb +0 -38
- data/lib/bali/foundations/exceptions/dsl_error.rb +0 -3
- data/lib/bali/foundations/exceptions/objection_error.rb +0 -3
- data/lib/bali/foundations/judger/judge.rb +0 -329
- data/lib/bali/foundations/judger/negative_judge.rb +0 -40
- data/lib/bali/foundations/judger/positive_judge.rb +0 -41
- data/lib/bali/foundations/role_extractor.rb +0 -61
- data/lib/bali/foundations/rule/rule.rb +0 -55
- data/lib/bali/foundations/rule/rule_class.rb +0 -54
- data/lib/bali/foundations/rule/rule_group.rb +0 -91
- data/lib/bali/integrators/all_integrators.rb +0 -8
- data/lib/bali/integrators/rule_class_integrator.rb +0 -27
- data/lib/bali/integrators/rule_group_integrator.rb +0 -29
- data/lib/bali/integrators/rule_integrator.rb +0 -56
- data/lib/bali/objector.rb +0 -173
@@ -1,75 +0,0 @@
|
|
1
|
-
# grand scheme of things begin here
|
2
|
-
class Bali::MapRulesDsl
|
3
|
-
attr_accessor :current_rule_class
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@@lock ||= Mutex.new
|
7
|
-
end
|
8
|
-
|
9
|
-
# defining rules
|
10
|
-
def rules_for(target_class, options_hash = {}, &block)
|
11
|
-
@@lock.synchronize do
|
12
|
-
self.current_rule_class = Bali::RuleClass.new(target_class)
|
13
|
-
|
14
|
-
parent_class = options_hash[:inherits] || options_hash["inherits"]
|
15
|
-
if parent_class
|
16
|
-
# in case there is inherits specification
|
17
|
-
parent_is_class = parent_class.class
|
18
|
-
fail Bali::DslError, 'inherits must take a class' unless parent_is_class
|
19
|
-
rule_class_from_parent = Bali::Integrator::RuleClass.for(parent_class)
|
20
|
-
fail Bali::DslError, "not yet defined a rule class for #{parent_class}" if rule_class_from_parent.nil?
|
21
|
-
self.current_rule_class = rule_class_from_parent.clone(target_class: target_class)
|
22
|
-
end
|
23
|
-
|
24
|
-
Bali::RulesForDsl.new(self).instance_eval(&block)
|
25
|
-
|
26
|
-
# done processing the block, now add the rule class
|
27
|
-
Bali::Integrator::RuleClass.add(self.current_rule_class)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# subtarget_class is the subtarget's class definition
|
32
|
-
# field_name is the field that will be consulted when instantiated object of this class is passed in can? or cant?
|
33
|
-
def roles_for(subtarget_class, field_name)
|
34
|
-
Bali::TRANSLATED_SUBTARGET_ROLES[subtarget_class.to_s] = field_name
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
|
38
|
-
def describe(*params)
|
39
|
-
fail Bali::DslError, "describe block must be within rules_for block"
|
40
|
-
end
|
41
|
-
|
42
|
-
def role(*params)
|
43
|
-
fail Bali::DslError, "role block must be within rules_for block"
|
44
|
-
end
|
45
|
-
|
46
|
-
def can(*params)
|
47
|
-
fail Bali::DslError, "can block must be within role block"
|
48
|
-
end
|
49
|
-
|
50
|
-
def cant(*params)
|
51
|
-
puts "Deprecation Warning: declaring rules with cant will be deprecated on major release 3.0, use cannot instead"
|
52
|
-
cannot *params
|
53
|
-
end
|
54
|
-
|
55
|
-
def cannot(*params)
|
56
|
-
fail Bali::DslError, "cant block must be within role block"
|
57
|
-
end
|
58
|
-
|
59
|
-
def can_all(*params)
|
60
|
-
fail Bali::DslError, "can_all block must be within role block"
|
61
|
-
end
|
62
|
-
|
63
|
-
def clear_rules
|
64
|
-
fail Bali::DslError, "clear_rules must be called within role block"
|
65
|
-
end
|
66
|
-
|
67
|
-
def cant_all(*params)
|
68
|
-
puts "Deprecation Warning: declaring rules with cant_all will be deprecated on major release 3.0, use cannot instead"
|
69
|
-
cannot_all *params
|
70
|
-
end
|
71
|
-
|
72
|
-
def cannot_all(*params)
|
73
|
-
fail Bali::DslError, "cant_all block must be within role block"
|
74
|
-
end
|
75
|
-
end
|
@@ -1,130 +0,0 @@
|
|
1
|
-
# this class is used to define DSL after rules_for is invoked.
|
2
|
-
# @author Adam Pahlevi Baihaqi
|
3
|
-
class Bali::RulesForDsl
|
4
|
-
attr_accessor :map_rules_dsl
|
5
|
-
attr_accessor :current_rule_group
|
6
|
-
|
7
|
-
# all to be processed subtargets
|
8
|
-
attr_accessor :current_subtargets
|
9
|
-
|
10
|
-
def initialize(map_rules_dsl)
|
11
|
-
@@lock ||= Mutex.new
|
12
|
-
self.map_rules_dsl = map_rules_dsl
|
13
|
-
end
|
14
|
-
|
15
|
-
def current_rule_class
|
16
|
-
self.map_rules_dsl.current_rule_class
|
17
|
-
end
|
18
|
-
protected :current_rule_class
|
19
|
-
|
20
|
-
def role(*params)
|
21
|
-
@@lock.synchronize do
|
22
|
-
bali_scrap_actors(*params)
|
23
|
-
current_subtargets.each do |subtarget|
|
24
|
-
bali_set_subtarget(subtarget)
|
25
|
-
|
26
|
-
if block_given?
|
27
|
-
yield
|
28
|
-
else
|
29
|
-
# if no block, then rules are defined using shortcut notation, eg:
|
30
|
-
# role :user, can: [:edit]
|
31
|
-
# the last element of which params must be a hash
|
32
|
-
shortcut_rules = params[-1]
|
33
|
-
unless shortcut_rules.is_a?(Hash)
|
34
|
-
raise Bali::DslError, "Pass a hash for shortcut notation"
|
35
|
-
end
|
36
|
-
|
37
|
-
shortcut_can_rules = shortcut_rules[:can] || shortcut_rules["can"]
|
38
|
-
shortcut_cannot_rules = shortcut_rules[:cannot] || shortcut_rules["cannot"]
|
39
|
-
|
40
|
-
shortcut_rules.each do |auth_val, args|
|
41
|
-
Bali::Integrator::Rule.add(auth_val, self.current_rule_group, *args)
|
42
|
-
end # each shortcut rules
|
43
|
-
end # whether block is given or not
|
44
|
-
end # each subtarget
|
45
|
-
end # sync
|
46
|
-
end # role
|
47
|
-
|
48
|
-
def describe(*params)
|
49
|
-
puts "Bali Deprecation Warning: describing rules using describe will be deprecated on major release 3.0, use role instead"
|
50
|
-
if block_given?
|
51
|
-
role(*params) do
|
52
|
-
yield
|
53
|
-
end
|
54
|
-
else
|
55
|
-
role(*params)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# others block
|
60
|
-
def others(*params)
|
61
|
-
if block_given?
|
62
|
-
role("__*__") do
|
63
|
-
yield
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end # others
|
67
|
-
|
68
|
-
# clear all defined rules
|
69
|
-
def clear_rules
|
70
|
-
self.current_rule_group.clear_rules
|
71
|
-
true
|
72
|
-
end
|
73
|
-
|
74
|
-
def can(*args)
|
75
|
-
Bali::Integrator::Rule.add_can(self.current_rule_group, *args)
|
76
|
-
end
|
77
|
-
|
78
|
-
def cannot(*args)
|
79
|
-
Bali::Integrator::Rule.add_cannot(self.current_rule_group, *args)
|
80
|
-
end
|
81
|
-
|
82
|
-
def cant(*operations)
|
83
|
-
puts "Deprecation Warning: declaring rules with cant will be deprecated on major release 3.0, use cannot instead"
|
84
|
-
cannot(*operations)
|
85
|
-
end
|
86
|
-
|
87
|
-
def can_all
|
88
|
-
Bali::Integrator::RuleGroup.make_zeus(self.current_rule_group)
|
89
|
-
end
|
90
|
-
|
91
|
-
def cannot_all
|
92
|
-
Bali::Integrator::RuleGroup.make_plant(self.current_rule_group)
|
93
|
-
end
|
94
|
-
|
95
|
-
def cant_all
|
96
|
-
puts "Deprecation Warning: declaring rules with cant_all will be deprecated on major release 3.0, use cannot_all instead"
|
97
|
-
cannot_all
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
def bali_scrap_actors(*params)
|
102
|
-
self.current_subtargets = []
|
103
|
-
params.each do |passed_argument|
|
104
|
-
if passed_argument.is_a?(Symbol) || passed_argument.is_a?(String)
|
105
|
-
self.current_subtargets << passed_argument
|
106
|
-
elsif passed_argument.is_a?(NilClass)
|
107
|
-
self.current_subtargets << passed_argument
|
108
|
-
elsif passed_argument.is_a?(Array)
|
109
|
-
self.current_subtargets += passed_argument
|
110
|
-
end
|
111
|
-
end
|
112
|
-
nil
|
113
|
-
end
|
114
|
-
|
115
|
-
# set the current processing on a specific subtarget
|
116
|
-
def bali_set_subtarget(subtarget)
|
117
|
-
rule_class = self.map_rules_dsl.current_rule_class
|
118
|
-
target_class = rule_class.target_class
|
119
|
-
|
120
|
-
rule_group = rule_class.rules_for(subtarget)
|
121
|
-
|
122
|
-
if rule_group.nil?
|
123
|
-
rule_group = Bali::RuleGroup.new(target_class, subtarget)
|
124
|
-
end
|
125
|
-
|
126
|
-
rule_class.add_rule_group rule_group
|
127
|
-
self.current_rule_group = rule_group
|
128
|
-
end
|
129
|
-
|
130
|
-
end # class
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# ./exceptions
|
2
|
-
require_relative "exceptions/bali_error"
|
3
|
-
require_relative "exceptions/dsl_error"
|
4
|
-
require_relative "exceptions/objection_error"
|
5
|
-
require_relative "exceptions/authorization_error"
|
6
|
-
|
7
|
-
# rule
|
8
|
-
require_relative "rule/rule"
|
9
|
-
require_relative "rule/rule_class"
|
10
|
-
require_relative "rule/rule_group"
|
11
|
-
|
12
|
-
# role extractor
|
13
|
-
require_relative "role_extractor"
|
14
|
-
|
15
|
-
require_relative "judger/judge"
|
16
|
-
require_relative "judger/negative_judge"
|
17
|
-
require_relative "judger/positive_judge"
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# Error that will be raised when subtarget cannot do something he wanted to do,
|
2
|
-
# or when subtarget do something he should not be allowed to do.
|
3
|
-
class Bali::AuthorizationError < Bali::Error
|
4
|
-
attr_accessor :operation
|
5
|
-
attr_accessor :auth_level
|
6
|
-
attr_accessor :role
|
7
|
-
|
8
|
-
# it may be nil, depends on whether rule checking is using symbol/user
|
9
|
-
attr_accessor :subtarget
|
10
|
-
|
11
|
-
# whether a class or an object
|
12
|
-
attr_accessor :target
|
13
|
-
|
14
|
-
def target_proper_class
|
15
|
-
if target.is_a?(Class)
|
16
|
-
target
|
17
|
-
else
|
18
|
-
target.class
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
role = humanise_value(self.role)
|
24
|
-
operation = humanise_value(self.operation)
|
25
|
-
auth_level = humanise_value(self.auth_level)
|
26
|
-
|
27
|
-
if auth_level == :can
|
28
|
-
"Role #{role} is not allowed to perform operation `#{operation}` on #{target_proper_class}"
|
29
|
-
else
|
30
|
-
"Role #{role} is allowed to perform operation `#{operation}` on #{target_proper_class}"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
def humanise_value(val)
|
36
|
-
val.nil? ? "<nil>" : val
|
37
|
-
end
|
38
|
-
end
|
@@ -1,329 +0,0 @@
|
|
1
|
-
module Bali::Judger
|
2
|
-
# FUZY-ed value is happen when it is not really clear, need further cross checking,
|
3
|
-
# whether it is really allowed or not. It happens for example in block with others, such as this:
|
4
|
-
#
|
5
|
-
# role :finance do
|
6
|
-
# cannot :view
|
7
|
-
# end
|
8
|
-
# others do
|
9
|
-
# can :view
|
10
|
-
# can :index
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# In the example above, objecting cannot view on finance will result in STRONG_FALSE, but
|
14
|
-
# objecting can index on finance will result in FUZY_TRUE.
|
15
|
-
#
|
16
|
-
# Eventually, all FUZY value will be normal TRUE or FALSE if no definite counterpart
|
17
|
-
# is found/defined
|
18
|
-
BALI_FUZY_FALSE = -2
|
19
|
-
BALI_FUZY_TRUE = 2
|
20
|
-
BALI_FALSE = -1
|
21
|
-
BALI_TRUE = 1
|
22
|
-
|
23
|
-
class Judge
|
24
|
-
attr_accessor :original_subtarget
|
25
|
-
attr_accessor :subtarget
|
26
|
-
attr_accessor :operation
|
27
|
-
# record can be the class, or an instance of a class
|
28
|
-
attr_accessor :record
|
29
|
-
|
30
|
-
# determine if this judger should not call other judger
|
31
|
-
attr_accessor :cross_checking
|
32
|
-
|
33
|
-
# this class is abstract, shouldn't be initialized
|
34
|
-
def initialize(unconstructable = true)
|
35
|
-
if unconstructable
|
36
|
-
raise Bali::Error, "Bali::Judge::Judger is unconstructable, properly construct by using build to get a concrete class!"
|
37
|
-
end
|
38
|
-
self
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.build(auth_level, options = {})
|
42
|
-
judge = nil
|
43
|
-
if auth_level == :can
|
44
|
-
judge = Bali::Judger::PositiveJudge.new
|
45
|
-
elsif auth_level == :cannot
|
46
|
-
judge = Bali::Judger::NegativeJudge.new
|
47
|
-
else
|
48
|
-
raise Bali::Error, "Unable to find judge for `#{auth_level}` case"
|
49
|
-
end
|
50
|
-
|
51
|
-
judge.original_subtarget = options[:original_subtarget]
|
52
|
-
judge.subtarget = options[:subtarget]
|
53
|
-
judge.operation = options[:operation]
|
54
|
-
judge.record = options[:record]
|
55
|
-
judge.cross_checking = false
|
56
|
-
|
57
|
-
judge
|
58
|
-
end
|
59
|
-
|
60
|
-
def clone(options = {})
|
61
|
-
if options[:reverse]
|
62
|
-
new_judge = Bali::Judger::Judge.build(self.reverse_auth_level)
|
63
|
-
else
|
64
|
-
new_judge = Bali::Judger::Judge.build(self.auth_level)
|
65
|
-
end
|
66
|
-
|
67
|
-
new_judge.subtarget = subtarget
|
68
|
-
new_judge.operation = operation
|
69
|
-
new_judge.record = record
|
70
|
-
new_judge.cross_checking = cross_checking
|
71
|
-
new_judge.original_subtarget = original_subtarget
|
72
|
-
|
73
|
-
new_judge
|
74
|
-
end
|
75
|
-
|
76
|
-
def record_class
|
77
|
-
record.is_a?(Class) ? record : record.class
|
78
|
-
end
|
79
|
-
|
80
|
-
def rule_group
|
81
|
-
unless @rule_group_checked
|
82
|
-
@rule_group = Bali::Integrator::RuleGroup.for(record_class, subtarget)
|
83
|
-
@rule_group_checked = true
|
84
|
-
end
|
85
|
-
@rule_group
|
86
|
-
end
|
87
|
-
|
88
|
-
def other_rule_group
|
89
|
-
unless @other_rule_group_checked
|
90
|
-
@other_rule_group = Bali::Integrator::RuleGroup.for(record_class, "__*__")
|
91
|
-
@other_rule_group_checked = true
|
92
|
-
end
|
93
|
-
@other_rule_group
|
94
|
-
end
|
95
|
-
|
96
|
-
def rule
|
97
|
-
unless @rule_checked
|
98
|
-
# rule group may be nil, for when user checking for undefined rule group
|
99
|
-
if rule_group
|
100
|
-
@rule = rule_group.get_rule(auth_level, operation)
|
101
|
-
else
|
102
|
-
self.rule = nil
|
103
|
-
end
|
104
|
-
end
|
105
|
-
@rule
|
106
|
-
end
|
107
|
-
|
108
|
-
def rule=(the_rule)
|
109
|
-
@rule = the_rule
|
110
|
-
@rule_checked = true
|
111
|
-
@rule
|
112
|
-
end
|
113
|
-
|
114
|
-
def otherly_rule
|
115
|
-
unless @otherly_rule_checked
|
116
|
-
if other_rule_group
|
117
|
-
# retrieve rule from others group
|
118
|
-
@otherly_rule = other_rule_group.get_rule(auth_level, operation)
|
119
|
-
@otherly_rule_checked = true
|
120
|
-
end
|
121
|
-
end
|
122
|
-
@otherly_rule
|
123
|
-
end
|
124
|
-
|
125
|
-
# return either true or false
|
126
|
-
# options can specify if returning raw, by specifying holy: true
|
127
|
-
def judgement(options = {})
|
128
|
-
# the divine judgement will come to thee, O Thou
|
129
|
-
# the doer of truth. return raw, untranslated to true/false.
|
130
|
-
our_holy_judgement = nil
|
131
|
-
|
132
|
-
# default of can? is false whenever RuleClass for that class is undefined
|
133
|
-
# or RuleGroup for that subtarget is not defined
|
134
|
-
if rule_group.nil?
|
135
|
-
if other_rule_group.nil?
|
136
|
-
# no more chance for checking
|
137
|
-
our_holy_judgement = natural_value
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
if our_holy_judgement.nil? && need_to_check_for_intervention?
|
142
|
-
our_holy_judgement = check_intervention
|
143
|
-
end
|
144
|
-
|
145
|
-
if our_holy_judgement.nil? &&
|
146
|
-
rule_group && rule_group.plant? &&
|
147
|
-
rule.nil? && otherly_rule.nil?
|
148
|
-
our_holy_judgement = natural_value
|
149
|
-
end
|
150
|
-
|
151
|
-
if our_holy_judgement.nil? && rule.nil?
|
152
|
-
cross_check_value = nil
|
153
|
-
# default if can? for undefined rule is false, after related clause
|
154
|
-
# cannot be found in cannot?
|
155
|
-
unless cross_checking
|
156
|
-
reversed_self = self.clone reverse: true
|
157
|
-
reversed_self.cross_checking = true
|
158
|
-
cross_check_value = reversed_self.judgement holy: true
|
159
|
-
end
|
160
|
-
|
161
|
-
# if cross check value nil, then the reverse rule is not defined,
|
162
|
-
# let's determine whether he is zeus or plant
|
163
|
-
if cross_check_value.nil?
|
164
|
-
# rule_group can be nil for when user checking under undefined rule-group
|
165
|
-
if rule_group
|
166
|
-
if rule_group.plant?
|
167
|
-
our_holy_judgement = plant_return_value
|
168
|
-
end
|
169
|
-
|
170
|
-
if rule_group.zeus?
|
171
|
-
our_holy_judgement = zeus_return_value
|
172
|
-
end
|
173
|
-
end # if rule_group exist
|
174
|
-
else
|
175
|
-
# process value from cross checking
|
176
|
-
|
177
|
-
if can_use_otherly_rule?(cross_check_value, cross_checking)
|
178
|
-
# give chance to check at others block
|
179
|
-
self.rule = otherly_rule
|
180
|
-
else
|
181
|
-
our_holy_judgement = cross_check_reverse_value(cross_check_value)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end # if our judgement nil and rule is nil
|
185
|
-
|
186
|
-
# if our holy judgement is still nil, but rule is defined
|
187
|
-
if our_holy_judgement.nil? && rule
|
188
|
-
if rule.has_decider?
|
189
|
-
our_holy_judgement = get_decider_result(rule, original_subtarget, record)
|
190
|
-
else
|
191
|
-
our_holy_judgement = default_positive_return_value
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
# return fuzy if otherly rule defines contrary to this auth_level
|
196
|
-
if our_holy_judgement.nil? && rule.nil? && (other_rule_group && other_rule_group.get_rule(reverse_auth_level, operation))
|
197
|
-
if rule_group && (rule_group.zeus? || rule_group.plant?)
|
198
|
-
# don't overwrite our holy judgement with fuzy value if rule group
|
199
|
-
# zeus/plant, because zeus/plant is more definite than any fuzy values
|
200
|
-
# eventhough the rule is abstractly defined
|
201
|
-
else
|
202
|
-
our_holy_judgement = default_negative_fuzy_return_value
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
# if at this point still nil, well,
|
207
|
-
# return the natural value for this judge
|
208
|
-
if our_holy_judgement.nil?
|
209
|
-
if otherly_rule
|
210
|
-
our_holy_judgement = BALI_FUZY_TRUE
|
211
|
-
else
|
212
|
-
our_holy_judgement = natural_value
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
holy = !!options[:holy]
|
217
|
-
return holy ? our_holy_judgement : translate_holy_judgement(our_holy_judgement)
|
218
|
-
end
|
219
|
-
|
220
|
-
private
|
221
|
-
# translate response for value above to traditional true/false
|
222
|
-
# holy judgement refer to non-standard true/false being used inside Bali
|
223
|
-
# which need to be translated from other beings to know
|
224
|
-
def translate_holy_judgement(bali_bool_value)
|
225
|
-
unless bali_bool_value.is_a?(Integer)
|
226
|
-
raise Bali::Error, "Expect bali value to be an Integer, got: `#{bali_bool_value}`"
|
227
|
-
end
|
228
|
-
if bali_bool_value < 0
|
229
|
-
return false
|
230
|
-
elsif bali_bool_value > 0
|
231
|
-
return true
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def can_use_otherly_rule?(cross_check_value, is_cross_checking)
|
236
|
-
# either if rule from others block is defined, and the result so far is fuzy
|
237
|
-
# or, otherly rule is defined, and it is still a cross check
|
238
|
-
# plus, the result is not a definite BALI_TRUE/BALI_FALSE
|
239
|
-
#
|
240
|
-
# rationalisation:
|
241
|
-
# 1. Definite answer such as BALI_TRUE and BALI_FALSE is to be prioritised over
|
242
|
-
# FUZY answer, because definite answer is not gathered from others block where
|
243
|
-
# FUZY answer is. Therefore, it is an intended result
|
244
|
-
# 2. If the answer is FUZY, otherly_rule only be considered if the result
|
245
|
-
# is either FUZY TRUE or FUZY FALSE, or
|
246
|
-
# 3. Or, when already in cross check mode, we cannot retrieve cross_check_value
|
247
|
-
# what we can is instead, if otherly rule is available, just to try the odd
|
248
|
-
(!otherly_rule.nil? && cross_check_value && !(cross_check_value == BALI_TRUE || cross_check_value == BALI_FALSE)) ||
|
249
|
-
(!otherly_rule.nil? && (cross_check_value == BALI_FUZY_FALSE || cross_check_value == BALI_FUZY_TRUE)) ||
|
250
|
-
(!otherly_rule.nil? && is_cross_checking && cross_check_value.nil?)
|
251
|
-
end
|
252
|
-
|
253
|
-
# if after cross check (checking for cannot) the return is false,
|
254
|
-
# meaning for us, (checking for can), the return have to be true
|
255
|
-
def cross_check_reverse_value(cross_check_value)
|
256
|
-
# either the return is not fuzy, or otherly rule is undefined
|
257
|
-
if cross_check_value == BALI_TRUE
|
258
|
-
return BALI_FALSE
|
259
|
-
elsif cross_check_value == BALI_FALSE
|
260
|
-
return BALI_TRUE
|
261
|
-
elsif cross_check_value == BALI_FUZY_FALSE
|
262
|
-
return BALI_FUZY_TRUE
|
263
|
-
elsif cross_check_value == BALI_FUZY_TRUE
|
264
|
-
return BALI_FUZY_FALSE
|
265
|
-
else
|
266
|
-
raise Bali::Error, "Unknown how to process cross check value: `#{cross_check_value}`"
|
267
|
-
end
|
268
|
-
end # cross_check_reverse_value
|
269
|
-
|
270
|
-
def check_intervention
|
271
|
-
if rule.nil?
|
272
|
-
self_clone = self.clone reverse: true
|
273
|
-
self_clone.cross_checking = true
|
274
|
-
|
275
|
-
check_val = self_clone.judgement holy: true
|
276
|
-
|
277
|
-
# check further whether contradicting rule is defined to overwrite this
|
278
|
-
# super-power either can_all or cannot_all rule
|
279
|
-
if check_val == BALI_TRUE
|
280
|
-
# it is defined, must overwrite
|
281
|
-
return BALI_FALSE
|
282
|
-
else
|
283
|
-
# futher inspection said no such overwriting value is exist
|
284
|
-
return BALI_TRUE
|
285
|
-
end # check_val
|
286
|
-
end # if rule nil
|
287
|
-
end # check intervention
|
288
|
-
|
289
|
-
# what is the result when decider is executed
|
290
|
-
# rule: the rule object
|
291
|
-
# original subtarget: raw, unprocessed arugment passed as subtarget
|
292
|
-
def get_decider_result(rule, original_subtarget, record)
|
293
|
-
# must test first
|
294
|
-
decider = rule.decider
|
295
|
-
case decider.arity
|
296
|
-
when 0
|
297
|
-
if rule.decider_type == :if
|
298
|
-
return decider.() ? BALI_TRUE : BALI_FALSE
|
299
|
-
elsif rule.decider_type == :unless
|
300
|
-
unless decider.()
|
301
|
-
return BALI_TRUE
|
302
|
-
else
|
303
|
-
return BALI_FALSE
|
304
|
-
end
|
305
|
-
end
|
306
|
-
when 1
|
307
|
-
if rule.decider_type == :if
|
308
|
-
return decider.(record) ? BALI_TRUE : BALI_FALSE
|
309
|
-
elsif rule.decider_type == :unless
|
310
|
-
unless decider.(record)
|
311
|
-
return BALI_TRUE
|
312
|
-
else
|
313
|
-
return BALI_FALSE
|
314
|
-
end
|
315
|
-
end
|
316
|
-
when 2
|
317
|
-
if rule.decider_type == :if
|
318
|
-
return decider.(record, original_subtarget) ? BALI_TRUE : BALI_FALSE
|
319
|
-
elsif rule.decider_type == :unless
|
320
|
-
unless decider.(record, original_subtarget)
|
321
|
-
return BALI_TRUE
|
322
|
-
else
|
323
|
-
return BALI_FALSE
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
end
|
328
|
-
end # class
|
329
|
-
end # module
|