custom_boolean 0.1.2 → 0.1.3

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.
@@ -1,7 +1,12 @@
1
1
  Custom Boolean
2
2
  ==============
3
3
 
4
- Cute hack to have if/else_if/else conditions with user-defined truthiness
4
+ Cute hack to have if/else_if/else conditions with user-defined
5
+ truthiness.
6
+
7
+ * Implements various preset truth tests: Ruby, Python, Perl, C, Strict Boolean.
8
+ * Provides ability to completely customize truthiness.
9
+ * Provides common Boolean Operators (and, or, not) compatible with CustomBoolean
5
10
 
6
11
  Normal conditionals:
7
12
  --------------------
@@ -18,7 +23,7 @@ A Pythonic truthiness:
18
23
  ----------------------
19
24
 
20
25
  # redefine truthiness with the `truth_test` method
21
- CustomBoolean.truth_test = proc { |b| b && b != 0 && b != [] }
26
+ CustomBoolean.truth_test = CustomBoolean::PYTHON_TRUTH
22
27
 
23
28
  if!(0) {
24
29
  puts 'true'
@@ -44,3 +49,125 @@ A full example:
44
49
  }
45
50
 
46
51
  #=> "x is 5"
52
+
53
+
54
+ Nested ifs work fine:
55
+ -------------------------
56
+
57
+ x = :delighted
58
+ y = :aroused
59
+
60
+ if?(x == :sad) {
61
+ puts 'evaluates to true'
62
+ }.
63
+ else_if(x == :delighted) {
64
+ if?(y == :happy) {
65
+ puts 'delighted and happy'
66
+ }.
67
+ else_if(y == :aroused) {
68
+ puts 'delighted and aroused'
69
+ }.
70
+ else { puts 'just delighted' }
71
+ }.
72
+ else {
73
+ puts 'not delighted'
74
+ }
75
+
76
+
77
+ If expressions
78
+ ----------------
79
+
80
+ # prefixing `if!` with `+` invokes if-expression behaviour
81
+ +if!(false) {
82
+ :hello
83
+ }.
84
+ else {
85
+ :goodbye
86
+ }
87
+ #=> :goodbye
88
+
89
+ Full list of preset CustomBoolean truth tests
90
+ ----------------------------------------------
91
+
92
+ CustomBoolean::RUBY_TRUTH # the default
93
+ CustomBoolean::PYTHON_TRUTH
94
+ CustomBoolean::PERL_TRUTH
95
+ CustomBoolean::C_TRUTH
96
+ CustomBoolean::STRICT_TRUTH # (`true` or `false` only)
97
+
98
+ Use as follows:
99
+
100
+ CustomBoolean.truth_test = CustomBoolean::C_TRUTH
101
+
102
+ +if!(0) {
103
+ true
104
+ }.
105
+ else {
106
+ false
107
+ }
108
+ #=> false
109
+
110
+
111
+ Customizable truthiness
112
+ -------------------------
113
+
114
+ `CustomBoolean.truth_test` can be set to an arbitrary Proc:
115
+
116
+ # only :horse is true
117
+ CustomBoolean.truth_test = proc { |b| b == :horse }
118
+
119
+ if!(true) {
120
+ puts 'evaluates to true'
121
+ }.
122
+ else {
123
+ puts 'reached else'
124
+ }
125
+
126
+ if!(:horse) {
127
+ puts 'evaluates to true'
128
+ }.
129
+ else {
130
+ puts 'reached else'
131
+ }
132
+
133
+
134
+ Boolean operators
135
+ -----------------
136
+
137
+ The ordinary `&&` and `||` and `!` operators do not implement
138
+ CustomBoolean truthiness. Instead use `Object#and`, `Object#or`, and
139
+ `Object#negate` (or `Object#&` and `Object#|` and `true.&` and `false.|`, etc)
140
+
141
+ # use perl truthiness where "0" is false
142
+ CustomBoolean.truth_test = CustomBoolean::PERL_TRUTH
143
+
144
+ +if!(true & "0") {
145
+ true
146
+ }.
147
+ else {
148
+ false
149
+ }
150
+ #=> false
151
+
152
+ # Or use Object#and
153
+ +if!(true.and "0") {...}
154
+
155
+ # Use negate (rather than not)
156
+ +if!(negate("0")) { true } ##=> true
157
+
158
+ Testing truthiness of expressions
159
+ ----------------------------------
160
+
161
+ You can test the truthiness of an expression without using the
162
+ full machinery of if!/else_if/else. Just use the
163
+ `CustomBoolean.truthy?()` function:
164
+
165
+ CustomBoolean.truth_test = CustomBoolean::PERL_TRUTH
166
+ CustomBoolean.truthy?("0") #=> false
167
+
168
+ Feedback
169
+ -----------
170
+
171
+ Problems or bugs, file an issue!
172
+
173
+ Have fun!
@@ -8,13 +8,13 @@ require "#{direc}/custom_boolean/version"
8
8
  class CustomBoolean
9
9
  module Operators
10
10
 
11
- # Equivalent of **&&** for CustomBoolean truthiness.
12
- # Differs from regular **&&** as it uses CustomBoolean truthiness
11
+ # Equivalent of *&&* for CustomBoolean truthiness.
12
+ # Differs from regular *&&* as it uses CustomBoolean truthiness
13
13
  #
14
- # **NOTE:** It is usually better to use the {#and} alias, as fewer objects override this
14
+ # *NOTE:* It is usually better to use the {#and} alias, as fewer objects override this
15
15
  # method)
16
16
  #
17
- # @param The rhs of the boolean *and* operator
17
+ # @param other The rhs of the boolean *and* operator
18
18
  # @return [Boolean]
19
19
  # @example
20
20
  # obj1 & obj2
@@ -24,13 +24,13 @@ class CustomBoolean
24
24
  end
25
25
  alias_method :and, :"&"
26
26
 
27
- # Equivalent of **||** for CustomBoolean truthiness.
28
- # Differs from regular **||** as it uses CustomBoolean truthiness
27
+ # Equivalent of *||* for CustomBoolean truthiness.
28
+ # Differs from regular *||* as it uses CustomBoolean truthiness
29
29
  #
30
- # **NOTE:** It is usually better to use the {#or} alias, as fewer objects override this
30
+ # *NOTE:* It is usually better to use the {#or} alias, as fewer objects override this
31
31
  # method)
32
32
  #
33
- # @param The rhs of the boolean *or* operator
33
+ # @param other The rhs of the boolean *or* operator
34
34
  # @return [Boolean]
35
35
  # @example
36
36
  # obj1 | obj2
@@ -47,10 +47,10 @@ true.extend(CustomBoolean::Operators)
47
47
  false.extend(CustomBoolean::Operators)
48
48
  Object.send(:include, CustomBoolean::Operators)
49
49
 
50
- # Equivalent of **!** for CustomBoolean truthiness.
51
- # Differs from regular **!** as it uses CustomBoolean truthiness
50
+ # Equivalent of *!* for CustomBoolean truthiness.
51
+ # Differs from regular *!* as it uses CustomBoolean truthiness
52
52
  #
53
- # @param The expression to be negated
53
+ # @param expr The expression to be negated
54
54
  # @return [Boolean]
55
55
  # @example
56
56
  # negate(obj)
@@ -58,20 +58,21 @@ def negate(expr)
58
58
  !CustomBoolean.truthy?(expr)
59
59
  end
60
60
 
61
- # Equivalent of **if** for CustomBoolean truthiness.
62
- # Differs from regular **if** as it uses CustomBoolean truthiness
61
+ # Equivalent of *if* for CustomBoolean truthiness.
62
+ # Differs from regular *if* as it uses CustomBoolean truthiness
63
63
  #
64
64
  # @example basic usage
65
- # Use as follows: if_(condition) { ... }
66
- # Other conditionals chain on to the end of if_() as follows:
65
+ # # Use as follows:
66
+ # if_(condition) { ... }
67
67
  #
68
- # if_(condition) { ... }.else { ... }
68
+ # # Other conditionals chain on to the end of if_() as follows:
69
+ # if_(condition) { ... }
70
+ # .else { ... }
69
71
  # @example if-expression form
70
- # Can turn if_() statement into if-expression by prefixing with a `+`
71
- #
72
+ # # Can turn if_() statement into if-expression by prefixing with a `+`
72
73
  # value = +if_(true) { :hello }
73
74
  # value #=> :hello
74
- # @param an expression to evaluate
75
+ # @param condition an expression to evaluate
75
76
  # @return [CustomBoolean]
76
77
  # @yield the block will be executed if the condition evalues to true
77
78
  def if_(condition, &block)
@@ -91,7 +92,7 @@ class CustomBoolean
91
92
  attr_accessor :truth_value
92
93
 
93
94
  # @return [Object] The value of the block that was executed in the
94
- # if/else_if/else
95
+ # if/else_if/else
95
96
  attr_accessor :value
96
97
 
97
98
  class << self
@@ -105,32 +106,31 @@ class CustomBoolean
105
106
  # by CustomBoolean.truth_test.
106
107
  #
107
108
  # Built in Truth tests include:
108
- # CustomBoolean::RUBY_TRUTH
109
109
  #
110
- # CustomBoolean::PYTHON_TRUTH
110
+ # *CustomBoolean::RUBY_TRUTH*
111
+ #
112
+ # *CustomBoolean::PYTHON_TRUTH*
111
113
  #
112
- # CustomBoolean::PERL_TRUTH
114
+ # *CustomBoolean::PERL_TRUTH*
113
115
  #
114
- # CustomBoolean::C_TRUTH
116
+ # *CustomBoolean::C_TRUTH*
115
117
  #
116
- # CustomBoolean::STRICT_TRUTH
118
+ # *CustomBoolean::STRICT_TRUTH*
117
119
  #
118
120
  # @example changing truthiness to a preset
119
121
  # CustomBoolean.truth_test = CustomBoolean::PYTHON_TRUTH
120
122
  # @example user-defined truthiness
121
123
  # # only :horse is true:
122
124
  # CustomBoolean.truth_test = proc { |expr| expr == :horse }
123
- # @param an expression to evaluate
125
+ # @param condition an expression to evaluate
124
126
  # @return [Boolean]
125
127
  def truthy?(condition)
126
128
  self.truth_test.call(condition)
127
129
  end
128
130
  end
129
131
 
130
- # exception raised when conditionals invoked after an else
131
132
  InvalidConditional = Class.new(StandardError)
132
133
 
133
- # various ideas of truth
134
134
  RUBY_TRUTH = proc { |expr| expr }
135
135
  PYTHON_TRUTH = proc { |expr| expr && !(expr.respond_to?(:empty?) && expr.empty?) && expr != 0 }
136
136
  STRICT_TRUTH = proc { |expr| raise "Expression must be strictly true or false." if expr != true && expr != false; expr }
@@ -140,18 +140,20 @@ class CustomBoolean
140
140
  # default truth test is Ruby's
141
141
  self.truth_test = RUBY_TRUTH
142
142
 
143
+ # @param [Boolean, Symbol] truth_value
144
+ # @param block_value
143
145
  def initialize(truth_value, block_value)
144
146
  self.truth_value = truth_value
145
147
  self.value = block_value
146
148
  end
147
149
 
148
- # Prefixing +if_+ with `+` turns if-statement into if-expression
150
+ # Prefixing +if_+ with *+* turns if-statement into if-expression
149
151
  # by invoking #value on CustomBoolean object.
150
152
  # @return [Object] extracts the value of the if, transforming it
151
- # into an if-expression
153
+ # into an if-expression
152
154
  # @example single if-expression example
153
155
  # +if(true) { :hello } #=> :hello
154
- # +if(fale) { :hello } #=> nil
156
+ # +if(false) { :hello } #=> nil
155
157
  # @example if-else-expression example
156
158
  # +if(false) {
157
159
  # :hello
@@ -176,11 +178,10 @@ class CustomBoolean
176
178
  # else_if(cond2) {
177
179
  # :goodbye
178
180
  # }
179
- # @param [Object] an expression to evaluate
181
+ # @param condition an expression to evaluate
180
182
  # @return [CustomBoolean]
181
183
  # @yield the block will be executed if the condition evalues to true
182
- # (so long as no prior *else_if* or *if* has evaluated to true further
183
- # up the chain)
184
+ # (so long as no prior *else_if* or *if* has evaluated to true further up the chain)
184
185
  def else_if(condition, &block)
185
186
  raise InvalidConditional, "No further conditionals allowed after an else." if self.truth_value == :else_reached
186
187
 
@@ -218,8 +219,7 @@ class CustomBoolean
218
219
  # }
219
220
  # @return [CustomBoolean]
220
221
  # @yield the block will be executed if the condition evalues to true
221
- # (so long as no prior *else_if* or *if* has evaluated to true further
222
- # up the chain)
222
+ # (so long as no prior *else_if* or *if* has evaluated to true further up the chain)
223
223
  def else(&block)
224
224
  raise InvalidConditional, "No further conditionals allowed after an else." if self.truth_value == :else_reached
225
225
 
@@ -1,3 +1,3 @@
1
1
  class CustomBoolean
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: custom_boolean
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 29
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 1
8
- - 2
9
- version: 0.1.2
9
+ - 3
10
+ version: 0.1.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - John Mair (banisterfiend)
@@ -52,6 +53,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
52
53
  requirements:
53
54
  - - ">="
54
55
  - !ruby/object:Gem::Version
56
+ hash: 3
55
57
  segments:
56
58
  - 0
57
59
  version: "0"
@@ -60,6 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
62
  requirements:
61
63
  - - ">="
62
64
  - !ruby/object:Gem::Version
65
+ hash: 3
63
66
  segments:
64
67
  - 0
65
68
  version: "0"