Christian N. wrote:
hears 1000 functional programmers whine about return values getting
lost
Just so all those functional programmers don’t lose their return values:
class Object
def true?
TrueValue.new(yield)
end
def false?
TrueValue.new(nil)
end
end
class FalseClass
def true?
FalseValue.new(nil)
end
def false?
FalseValue.new(yield)
end
end
class NilClass
def true?
FalseValue.new(nil)
end
def false?
FalseValue.new(yield)
end
end
class BooleanValue
attr_reader :value
def initialize(val)
@value = val
end
def true?
self
end
def false?
self
end
end
class TrueValue < BooleanValue
def true?
TrueValue.new(yield)
end
end
class FalseValue < BooleanValue
def false?
FalseValue.new(yield)
end
end
require ‘test/unit’
class TestTrueFalse < Test::Unit::TestCase
def test_false_results
assert_equal nil, false.true? { no }.value
assert_equal yes, false.true? { no }.false? { yes }.value
assert_equal yes, false.false? { yes }.value
assert_equal yes, false.false? { yes }.true? { no }.value
end
def test_nil_results
assert_equal nil, nil.true? { no }.value
assert_equal yes, nil.true? { no }.false? { yes }.value
assert_equal yes, nil.false? { yes }.value
assert_equal yes, nil.false? { yes }.true? { no }.value
end
def test_true_results
assert_equal yes, true.true? { yes }.value
assert_equal yes, true.true? { yes }.false? { no }.value
assert_equal nil, true.false? { no }.value
assert_equal yes, true.false? { no }.true? { yes }.value
end
def test_object_results
assert_equal yes, “hi”.true? { yes }.value
assert_equal yes, “hi”.true? { yes }.false? { no }.value
assert_equal nil, “hi”.false? { no }.value
assert_equal yes, “hi”.false? { no }.true? { yes }.value
end
def test_true_true_chains
check_chain(true, :true?)
check_chain(“hi”, :true?)
assert_equal nil, nil.true? { no }.true? { no }.value
assert_equal nil, false.true? { no }.true? { no }.value
end
def test_false_false_chains
assert_equal nil, “hi”.false? { no }.false? { no }.value
assert_equal nil, true.false? { no }.false? { no }.value
check_chain(nil, :false?)
check_chain(false, :false?)
end
def check_chain(value, method)
i = 0
assert_equal 3,
value.
send(method) { i += 1 }.
send(method) { i += 2 }.value
assert_equal 3, i
end
def yes
:yes
end
def no
fail “Should never execute this”
end
end
–
– Jim W.