ternary_types 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +58 -0
- data/Rakefile +11 -0
- data/lib/ternary_types.rb +96 -0
- data/lib/ternary_types/version.rb +3 -0
- data/ternary_types.gemspec +24 -0
- data/test/ternary_types_test.rb +102 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 46426cac759835696bc9fd7ec9c4e4d23f613ecd
|
4
|
+
data.tar.gz: e1414aaf0aa2c9ea97d1cccf559ef3faa9e14d9a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec4d8cc6e150e22d29beb0bd8a3c932d5d25c9fb4fd412fc1d3001b3d0b334a6292bb0838c5a1868ea088c1b1739100f7d40e90feb22bbe282114a12fcb67a96
|
7
|
+
data.tar.gz: af929f5704333e80db9a3eb4141af2432dadf3e8d92d64521594e2a0ae881162cf559852f307551cd001bca0e916af792998075df968876bf1431e4f692762d6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Maxim Chernyak
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# ternary_types
|
2
|
+
|
3
|
+
Use True/False/Maybe singletons to evaluate 3-value logic for such great fun.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```irb
|
8
|
+
require 'ternary_types'
|
9
|
+
|
10
|
+
T = TernaryTypes::True.instance
|
11
|
+
M = TernaryTypes::Maybe.instance
|
12
|
+
F = TernaryTypes::Flase.instance
|
13
|
+
|
14
|
+
!T # => #<TernaryTypes::False:0x007feccc7c4938>
|
15
|
+
!M # => #<TernaryTypes::Maybe:0x007feccc7b61f8>
|
16
|
+
T == F # => #<TernaryTypes::True:0x007feccc7bc670>
|
17
|
+
M == T # => #<TernaryTypes::Maybe:0x007feccc7b61f8>
|
18
|
+
M == M # => #<TernaryTypes::Maybe:0x007feccc7b61f8>
|
19
|
+
T == T # => #<TernaryTypes::True:0x007feccc7bc670>
|
20
|
+
T & F # => #<TernaryTypes::False:0x007feccc7c4938>
|
21
|
+
M & T # => #<TernaryTypes::Maybe:0x007feccc7b61f8>
|
22
|
+
T | F # => #<TernaryTypes::True:0x007feccc7bc670>
|
23
|
+
T ^ T # => #<TernaryTypes::False:0x007feccc7c4938>
|
24
|
+
|
25
|
+
include TernaryTypes::Coersion
|
26
|
+
|
27
|
+
Ternary(true) # => #<TernaryTypes::True:0x007feccc7bc670>
|
28
|
+
Ternary(:foo) # => #<TernaryTypes::True:0x007feccc7bc670>
|
29
|
+
|
30
|
+
Ternary(false) # => #<TernaryTypes::False:0x007feccc7c4938>
|
31
|
+
Ternary(nil) # => #<TernaryTypes::False:0x007feccc7c4938>
|
32
|
+
|
33
|
+
Ternary(:maybe) # => #<TernaryTypes::Maybe:0x007feccc7b61f8>
|
34
|
+
```
|
35
|
+
|
36
|
+
## Installation
|
37
|
+
|
38
|
+
Add this line to your application's Gemfile:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
gem 'ternary_types'
|
42
|
+
```
|
43
|
+
|
44
|
+
And then execute:
|
45
|
+
|
46
|
+
$ bundle
|
47
|
+
|
48
|
+
Or install it yourself as:
|
49
|
+
|
50
|
+
$ gem install ternary_types
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
1. Fork it ( https://github.com/[my-github-username]/ternary_types/fork )
|
55
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
56
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
57
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
58
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'ternary_types/version'
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module TernaryTypes
|
5
|
+
module Coersion
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def Ternary(value)
|
9
|
+
if [True, False, Maybe].any?{|c| value.is_a?(c)}
|
10
|
+
value
|
11
|
+
elsif value == :maybe
|
12
|
+
Maybe.instance
|
13
|
+
elsif value
|
14
|
+
True.instance
|
15
|
+
else
|
16
|
+
False.instance
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class True
|
22
|
+
include Singleton
|
23
|
+
include Coersion
|
24
|
+
|
25
|
+
def true?; true end
|
26
|
+
def maybe?; false end
|
27
|
+
def false?; false end
|
28
|
+
def to_s; 'true' end
|
29
|
+
|
30
|
+
def !; False.instance end
|
31
|
+
def ==(other); other end
|
32
|
+
def &(other); other end
|
33
|
+
def |(other); self end
|
34
|
+
|
35
|
+
def ^(other)
|
36
|
+
case Ternary(other)
|
37
|
+
when True then False.instance
|
38
|
+
when Maybe then Maybe.instance
|
39
|
+
else self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Maybe
|
45
|
+
include Singleton
|
46
|
+
include Coersion
|
47
|
+
|
48
|
+
def true?; false end
|
49
|
+
def maybe?; true end
|
50
|
+
def false?; false end
|
51
|
+
def to_s; 'maybe' end
|
52
|
+
|
53
|
+
def !; self end
|
54
|
+
def ==(other); self end
|
55
|
+
def ^(other); self end
|
56
|
+
|
57
|
+
def &(other)
|
58
|
+
case Ternary(other)
|
59
|
+
when True then self
|
60
|
+
when Maybe then self
|
61
|
+
else False.instance
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def |(other)
|
66
|
+
case Ternary(other)
|
67
|
+
when True then True.instance
|
68
|
+
when Maybe then self
|
69
|
+
else self
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class False
|
75
|
+
include Singleton
|
76
|
+
include Coersion
|
77
|
+
|
78
|
+
def true?; false end
|
79
|
+
def maybe?; false end
|
80
|
+
def false?; true end
|
81
|
+
def to_s; 'false' end
|
82
|
+
|
83
|
+
def !; True.instance end
|
84
|
+
def &(other); self end
|
85
|
+
def |(other); other end
|
86
|
+
def ^(other); other end
|
87
|
+
|
88
|
+
def ==(other)
|
89
|
+
case Ternary(other)
|
90
|
+
when True then self
|
91
|
+
when Maybe then Maybe.instance
|
92
|
+
else True.instance
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ternary_types/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ternary_types"
|
8
|
+
spec.version = TernaryTypes::VERSION
|
9
|
+
spec.authors = ["Maxim Chernyak"]
|
10
|
+
spec.email = ["madfancier@gmail.com"]
|
11
|
+
spec.summary = %q{Use ternary types in your ruby apps.}
|
12
|
+
spec.description = 'Provides ternary singletons True, False, and Maybe '\
|
13
|
+
'with ==,!,&,|,^ operators implemented according to three-value logic.'
|
14
|
+
spec.homepage = "https://github.com/maxim/ternary_types"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'ternary_types'
|
4
|
+
|
5
|
+
class TernaryTypesTest < MiniTest::Unit::TestCase
|
6
|
+
T = TernaryTypes::True.instance
|
7
|
+
F = TernaryTypes::False.instance
|
8
|
+
M = TernaryTypes::Maybe.instance
|
9
|
+
|
10
|
+
include TernaryTypes::Coersion
|
11
|
+
|
12
|
+
def assert_true(exp, str)
|
13
|
+
assert exp.true?, "Expected #{str} to evaluate to #{T}, got #{exp}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_maybe(exp, str)
|
17
|
+
assert exp.maybe?, "Expected #{str} to evaluate to #{M}, got #{exp}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def assert_false(exp, str)
|
21
|
+
assert exp.false?, "Expected #{str} to evaluate to #{F}, got #{exp}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_equals
|
25
|
+
assert_true T == T, 'T == T'
|
26
|
+
assert_true F == F, 'F == F'
|
27
|
+
assert_maybe M == M, 'M == M'
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_not
|
31
|
+
assert_false !T, '!T'
|
32
|
+
assert_true !F, '!F'
|
33
|
+
assert_maybe !M, '!M'
|
34
|
+
end
|
35
|
+
|
36
|
+
# | F M T
|
37
|
+
# --+-------
|
38
|
+
# F | F F F
|
39
|
+
# M | F M M
|
40
|
+
# T | F M T
|
41
|
+
def test_and
|
42
|
+
assert_false F & F, 'F & F'
|
43
|
+
assert_false F & M, 'F & M'
|
44
|
+
assert_false F & T, 'F & T'
|
45
|
+
|
46
|
+
assert_false M & F, 'M & F'
|
47
|
+
assert_maybe M & M, 'M & M'
|
48
|
+
assert_maybe M & T, 'M & T'
|
49
|
+
|
50
|
+
assert_false T & F, 'T & F'
|
51
|
+
assert_maybe T & M, 'T & M'
|
52
|
+
assert_true T & T, 'T & T'
|
53
|
+
end
|
54
|
+
|
55
|
+
# | F M T
|
56
|
+
# --+-------
|
57
|
+
# F | F M T
|
58
|
+
# M | M M T
|
59
|
+
# T | T T T
|
60
|
+
def test_or
|
61
|
+
assert_false F | F, 'F | F'
|
62
|
+
assert_maybe F | M, 'F | M'
|
63
|
+
assert_true F | T, 'F | T'
|
64
|
+
|
65
|
+
assert_maybe M | F, 'M | F'
|
66
|
+
assert_maybe M | M, 'M | M'
|
67
|
+
assert_true M | T, 'M | T'
|
68
|
+
|
69
|
+
assert_true T | F, 'T | F'
|
70
|
+
assert_true T | M, 'T | M'
|
71
|
+
assert_true T | T, 'T | T'
|
72
|
+
end
|
73
|
+
|
74
|
+
# | F M T
|
75
|
+
# --+-------
|
76
|
+
# F | F M T
|
77
|
+
# M | M M M
|
78
|
+
# T | T M F
|
79
|
+
def test_xor
|
80
|
+
assert_false F ^ F, 'F ^ F'
|
81
|
+
assert_maybe F ^ M, 'F ^ M'
|
82
|
+
assert_true F ^ T, 'F ^ T'
|
83
|
+
|
84
|
+
assert_maybe M ^ F, 'M ^ F'
|
85
|
+
assert_maybe M ^ M, 'M ^ M'
|
86
|
+
assert_maybe M ^ T, 'M ^ T'
|
87
|
+
|
88
|
+
assert_true T ^ F, 'T ^ F'
|
89
|
+
assert_maybe T ^ M, 'T ^ M'
|
90
|
+
assert_false T ^ T, 'T ^ T'
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_coersion
|
94
|
+
assert_true Ternary(T), 'Ternary(T)'
|
95
|
+
assert_maybe Ternary(M), 'Ternary(M)'
|
96
|
+
assert_false Ternary(F), 'Ternary(F)'
|
97
|
+
assert_maybe Ternary(:maybe), 'Ternary(:maybe)'
|
98
|
+
assert_true Ternary(:object), 'Ternary(:object)'
|
99
|
+
assert_false Ternary(false), 'Ternary(false)'
|
100
|
+
assert_false Ternary(nil), 'Ternary(nil)'
|
101
|
+
end
|
102
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ternary_types
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maxim Chernyak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
description: Provides ternary singletons True, False, and Maybe with ==,!,&,|,^ operators
|
42
|
+
implemented according to three-value logic.
|
43
|
+
email:
|
44
|
+
- madfancier@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- Gemfile
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- lib/ternary_types.rb
|
55
|
+
- lib/ternary_types/version.rb
|
56
|
+
- ternary_types.gemspec
|
57
|
+
- test/ternary_types_test.rb
|
58
|
+
homepage: https://github.com/maxim/ternary_types
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 2.4.5
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Use ternary types in your ruby apps.
|
82
|
+
test_files:
|
83
|
+
- test/ternary_types_test.rb
|
84
|
+
has_rdoc:
|