taxon.benforeva 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/taxon.rb +15 -0
- data/lib/taxon/constraints.rb +18 -0
- data/lib/taxon/entity.rb +38 -0
- data/lib/taxon/guard.rb +33 -0
- data/lib/taxon/index.rb +59 -0
- data/lib/taxon/list.rb +60 -0
- data/lib/taxon/primitives.rb +22 -0
- data/lib/taxon/record.rb +23 -0
- data/lib/taxon/registry.rb +13 -0
- data/lib/taxon/table.rb +16 -0
- data/lib/taxon/tuple.rb +25 -0
- data/lib/taxon/union.rb +24 -0
- data/lib/taxon/version.rb +3 -0
- metadata +57 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 35053bb03dec9130af32c823e454b4325a11ad86
|
4
|
+
data.tar.gz: 88ac8249d3e574ef092dc944cdb2ed77601d816e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c788f1f9686e6b6026e14adbf228d05634634bf89928385935f326b0db7e38d7d7dd772bb938f3aff2a01bf8a98a62801e33478a30bc69a0669b87923233c4c1
|
7
|
+
data.tar.gz: f6466dbed1e9c20a94a784daa8bdda2bc6668b92e47b2073fed2b392457092db35e5db591cd25e36fb15f89680bf38a73d79fdcbff8a37bd54b71e3f08bb4572
|
data/lib/taxon.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'taxon/primitives.rb'
|
2
|
+
require_relative 'taxon/guard.rb'
|
3
|
+
require_relative 'taxon/tuple.rb'
|
4
|
+
require_relative 'taxon/list.rb'
|
5
|
+
require_relative 'taxon/record.rb'
|
6
|
+
require_relative 'taxon/constraints.rb'
|
7
|
+
require_relative 'taxon/table.rb'
|
8
|
+
require_relative 'taxon/index.rb'
|
9
|
+
require_relative 'taxon/entity.rb'
|
10
|
+
require_relative 'taxon/union.rb'
|
11
|
+
|
12
|
+
module Taxon
|
13
|
+
include Primitives, Tuple, Union, List, Record, Table, Constraints, Entity
|
14
|
+
extend self
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Constraints
|
2
|
+
|
3
|
+
def bounded?(data, min=nil, max=nil)
|
4
|
+
if ((min==nil)&&(max==nil))
|
5
|
+
true
|
6
|
+
elsif (min==nil)
|
7
|
+
data <= max
|
8
|
+
elsif (max==nil)
|
9
|
+
data >= min
|
10
|
+
else
|
11
|
+
(data <= max) && (data >= min)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def upper_bounded?(data, max=nil)
|
16
|
+
max==nil ? true : data <= max
|
17
|
+
end
|
18
|
+
end
|
data/lib/taxon/entity.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'primitives.rb'
|
2
|
+
require_relative 'tuple.rb'
|
3
|
+
require_relative 'record.rb'
|
4
|
+
require_relative 'guard.rb'
|
5
|
+
|
6
|
+
module Entity
|
7
|
+
|
8
|
+
module DefaultEntities
|
9
|
+
include Primitives, Record, Tuple
|
10
|
+
extend self
|
11
|
+
end
|
12
|
+
|
13
|
+
def entity?(data, pred, ns=DefaultEntities)
|
14
|
+
Taxon::Guard.predicate?(ns, pred) ? ns.send(pred, data) : false
|
15
|
+
end
|
16
|
+
|
17
|
+
def entity(data, ns=DefaultEntities)
|
18
|
+
to_entity_name entity_tests(ns).find{|i| ns.send(i, data)}
|
19
|
+
end
|
20
|
+
|
21
|
+
def entity_tests(ns=DefaultEntities)
|
22
|
+
entity_format_methods(ns).map{|m| m.intern}
|
23
|
+
end
|
24
|
+
|
25
|
+
def entity_format_methods(ns)
|
26
|
+
ns.public_instance_methods.select{|m| m.to_s.end_with?("?")}
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_entity_name(method_name)
|
30
|
+
if (method_name.is_a?(Symbol) || method_name.is_a?(String))
|
31
|
+
method_name.to_s.split("_").map{|i| to_entity_word(i)}.join
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_entity_word(word)
|
36
|
+
word.end_with?("?") ? word.gsub(/\?/, "").capitalize : word.capitalize
|
37
|
+
end
|
38
|
+
end
|
data/lib/taxon/guard.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Taxon
|
2
|
+
module Guard
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def predicate?(rec, meth)
|
6
|
+
meth.is_a?(Symbol) && rec.respond_to?(meth)
|
7
|
+
end
|
8
|
+
|
9
|
+
def predicates?(rec, meths)
|
10
|
+
meths.is_a?(Array) && meths.all?{|m| predicate?(rec, m)}
|
11
|
+
end
|
12
|
+
|
13
|
+
def varying_predicates?(rec, meths)
|
14
|
+
predicate?(rec, meths) || predicates?(rec, meths)
|
15
|
+
end
|
16
|
+
|
17
|
+
def record_key?(data)
|
18
|
+
data.is_a?(Symbol) || data.is_a?(String)
|
19
|
+
end
|
20
|
+
|
21
|
+
def record_keys?(data)
|
22
|
+
data.is_a?(Array) && data.all?{|i| record_key?(i)}
|
23
|
+
end
|
24
|
+
|
25
|
+
def record_target?(rec, data)
|
26
|
+
any_record?(data) && Guard.predicates?(rec, data.values)
|
27
|
+
end
|
28
|
+
|
29
|
+
def any_record?(data)
|
30
|
+
data.is_a?(Hash) && data.keys.all?{|i| record_key?(i)}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/taxon/index.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require_relative 'record.rb'
|
2
|
+
|
3
|
+
# An array of records with set semantics
|
4
|
+
module Taxon
|
5
|
+
module Index
|
6
|
+
include Record
|
7
|
+
|
8
|
+
def index(preds)
|
9
|
+
ind = Array.new
|
10
|
+
setup_index_keys(ind, preds)
|
11
|
+
setup_index_targets(ind, preds)
|
12
|
+
ind
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup_index_keys(index, preds)
|
16
|
+
if Guard.record_keys?(preds)
|
17
|
+
index.define_singleton_method(:index_keys) {preds}
|
18
|
+
elsif Guard.record_target?(self, preds)
|
19
|
+
index.define_singleton_method(:index_keys) {preds.keys}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_index_targets(index, targets)
|
24
|
+
if Guard.record_keys?(targets)
|
25
|
+
index.define_singleton_method(:index_targets) {}
|
26
|
+
elsif Guard.record_target?(self, targets)
|
27
|
+
index.define_singleton_method(:index_targets) {targets}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def index?(data)
|
32
|
+
data.is_a?(Array) &&
|
33
|
+
data.respond_to?(:index_keys) &&
|
34
|
+
data.respond_to?(:index_targets)
|
35
|
+
end
|
36
|
+
|
37
|
+
def add(index, record, ignore=ignore_keys)
|
38
|
+
if nothing?(index.index_targets)
|
39
|
+
unique_insert(index, record, ignore) if record?(record, index.index_keys)
|
40
|
+
else
|
41
|
+
unique_insert(index, record, ignore) if record?(record, index.index_targets)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def unique_insert(index, record, ignore=ignore_keys)
|
46
|
+
index.all?{|e| is_unique_entry(e, record, ignore)} ? index.push(record) : index
|
47
|
+
end
|
48
|
+
|
49
|
+
def is_unique_entry(entry, record, ignore=ignore_keys)
|
50
|
+
keys = (entry.keys - ignore).any?{|i| entry[i] != record[i]}
|
51
|
+
end
|
52
|
+
|
53
|
+
def ignore_keys
|
54
|
+
[:uuid, :UUID, :id, :Id, :ID]
|
55
|
+
end
|
56
|
+
|
57
|
+
extend self
|
58
|
+
end
|
59
|
+
end
|
data/lib/taxon/list.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative 'tuple.rb'
|
2
|
+
require_relative 'primitives.rb'
|
3
|
+
require_relative 'guard.rb'
|
4
|
+
|
5
|
+
module List
|
6
|
+
include Tuple, Primitives
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def has_matching_elements(seq)
|
10
|
+
type = seq[0].class
|
11
|
+
seq.all?{|i| i.is_a?(type)}
|
12
|
+
end
|
13
|
+
|
14
|
+
def any_list?(seq)
|
15
|
+
any_tuple?(seq) && has_matching_elements(seq)
|
16
|
+
end
|
17
|
+
|
18
|
+
def list?(seq, pred=nil)
|
19
|
+
if any_tuple?(seq)
|
20
|
+
Taxon::Guard.predicate?(self, pred) ? seq.all?{|i| send(pred, i)} : any_list?(seq)
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def list(data, pred)
|
27
|
+
if varying?(data, pred)
|
28
|
+
send(pred, data) ? [data] : data
|
29
|
+
else
|
30
|
+
[]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def varying?(data, pred)
|
35
|
+
if Taxon::Guard.predicate?(self, pred)
|
36
|
+
def multiple?(data, pred)
|
37
|
+
list?(data, pred)
|
38
|
+
end
|
39
|
+
send(pred, data) || send(:multiple?, data, pred)
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def symbols?(data)
|
46
|
+
list?(data, :symbol?)
|
47
|
+
end
|
48
|
+
|
49
|
+
def numbers?(data)
|
50
|
+
list?(data, :number?)
|
51
|
+
end
|
52
|
+
|
53
|
+
def strings?(data)
|
54
|
+
list?(data, :string?)
|
55
|
+
end
|
56
|
+
|
57
|
+
def nothings?(data)
|
58
|
+
list?(data, :nothing?)
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Primitives
|
2
|
+
|
3
|
+
def nothing?(data)
|
4
|
+
data == nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def number?(data)
|
8
|
+
data.is_a? Numeric
|
9
|
+
end
|
10
|
+
|
11
|
+
def string?(data)
|
12
|
+
data.is_a? String
|
13
|
+
end
|
14
|
+
|
15
|
+
def symbol?(data)
|
16
|
+
data.is_a? Symbol
|
17
|
+
end
|
18
|
+
|
19
|
+
def boolean?(data)
|
20
|
+
data.is_a?(TrueClass) || data.is_a?(FalseClass)
|
21
|
+
end
|
22
|
+
end
|
data/lib/taxon/record.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'primitives.rb'
|
2
|
+
require_relative 'guard.rb'
|
3
|
+
|
4
|
+
module Record
|
5
|
+
include Primitives
|
6
|
+
|
7
|
+
def any_record?(data)
|
8
|
+
Taxon::Guard.any_record?(data)
|
9
|
+
end
|
10
|
+
|
11
|
+
def record?(data, pred=nil)
|
12
|
+
if Taxon::Guard.record_key?(pred)
|
13
|
+
any_record?(data) && data.has_key?(pred)
|
14
|
+
elsif Taxon::Guard.record_keys?(pred)
|
15
|
+
any_record?(data) && pred.all?{|i| data.has_key?(i)}
|
16
|
+
elsif Taxon::Guard.record_target?(self, pred)
|
17
|
+
data.is_a?(Hash) &&
|
18
|
+
pred.entries.all?{|k, v| data.has_key?(k) && send(v, data[k])}
|
19
|
+
else
|
20
|
+
any_record?(data)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/taxon/table.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'tuple.rb'
|
2
|
+
require_relative 'record.rb'
|
3
|
+
|
4
|
+
module Table
|
5
|
+
include Tuple, Record
|
6
|
+
|
7
|
+
def tabular?(data)
|
8
|
+
any_tuple?(data) &&
|
9
|
+
data.all?{|i| any_record?(i)}
|
10
|
+
end
|
11
|
+
|
12
|
+
def table?(data, pred=nil)
|
13
|
+
any_tuple?(data) &&
|
14
|
+
data.all?{|i| record?(i, pred)}
|
15
|
+
end
|
16
|
+
end
|
data/lib/taxon/tuple.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'guard.rb'
|
2
|
+
|
3
|
+
module Tuple
|
4
|
+
|
5
|
+
def empty_tuple?(seq)
|
6
|
+
any_tuple?(seq) && seq.empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def any_tuple?(seq)
|
10
|
+
seq.is_a?(Array)
|
11
|
+
end
|
12
|
+
|
13
|
+
def tuple?(tuple, entry_tests=[])
|
14
|
+
if empty_tuple?(entry_tests)
|
15
|
+
any_tuple?(tuple)
|
16
|
+
elsif Taxon::Guard.varying_predicates?(self, entry_tests)
|
17
|
+
if entry_tests.is_a? Array
|
18
|
+
upper = [tuple.size, entry_tests.size].min
|
19
|
+
(0...upper).all?{|i| send(entry_tests[i], tuple[i])}
|
20
|
+
else
|
21
|
+
send(entry_tests, tuple[0])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/taxon/union.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'primitives.rb'
|
2
|
+
require_relative 'guard.rb'
|
3
|
+
|
4
|
+
module Taxon
|
5
|
+
module Union
|
6
|
+
include Primitives
|
7
|
+
|
8
|
+
def any?(data)
|
9
|
+
data.is_a? Object
|
10
|
+
end
|
11
|
+
|
12
|
+
def union?(data, pred=:any?)
|
13
|
+
if Taxon::Guard.varying_predicates?(self, pred)
|
14
|
+
if Taxon::Guard.predicate?(self, pred)
|
15
|
+
send(pred, data)
|
16
|
+
else
|
17
|
+
pred.any?{|i| send(i, data)}
|
18
|
+
end
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: taxon.benforeva
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andre Dickson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-24 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Taxon lets you write class-free Ruby programs that are extremely explicit
|
14
|
+
about the entities they operate on.
|
15
|
+
email: taxon@andredickson.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/taxon.rb
|
21
|
+
- lib/taxon/constraints.rb
|
22
|
+
- lib/taxon/entity.rb
|
23
|
+
- lib/taxon/guard.rb
|
24
|
+
- lib/taxon/index.rb
|
25
|
+
- lib/taxon/list.rb
|
26
|
+
- lib/taxon/primitives.rb
|
27
|
+
- lib/taxon/record.rb
|
28
|
+
- lib/taxon/registry.rb
|
29
|
+
- lib/taxon/table.rb
|
30
|
+
- lib/taxon/tuple.rb
|
31
|
+
- lib/taxon/union.rb
|
32
|
+
- lib/taxon/version.rb
|
33
|
+
homepage: https://bitbucket.org/benforeva/taxon/src/master/
|
34
|
+
licenses:
|
35
|
+
- MIT
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 2.6.14.1
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: class-free programming for Ruby
|
57
|
+
test_files: []
|