typist 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +2 -1
- data/lib/typist.rb +6 -5
- data/lib/typist/data.rb +8 -1
- data/lib/typist/data_func.rb +15 -0
- data/lib/typist/version.rb +1 -1
- data/spec/lib/typist/constructor_spec.rb +13 -13
- data/spec/lib/typist/data_func_spec.rb +27 -0
- data/spec/lib/typist/data_spec.rb +44 -22
- data/spec/lib/typist/func_spec.rb +4 -5
- data/spec/lib/typist/util_spec.rb +1 -1
- data/spec/lib/typist_spec.rb +5 -7
- data/spec/spec_helper.rb +7 -0
- data/typist.gemspec +1 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17bc1b93c362a0acb4e9a516fe1cb6c85a8c12a3
|
4
|
+
data.tar.gz: 3cd4d3c01a379011988c50e9031a84a1925ecaec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb13350571688260b0f45e3b7892d3a9208f213adac413d156f1ee42688d9d15731c5f8402d1059d21e10aaca32b3ca9a38f406de697b1ecff034533baf5cbbe
|
7
|
+
data.tar.gz: c737d01ea3eb776eb4fcc337ca00638cc6a27d53ad2e096f0be98cefb8ca6fb1cdc134dc106802b3aac963a3abec7dab4ab6311d0df78f7dcf75d2740a3ef2b6
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# typist
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/typist)
|
3
4
|
[](https://travis-ci.org/nahiluhmot/typist)
|
4
5
|
[](https://codeclimate.com/github/nahiluhmot/typist)
|
5
6
|
|
@@ -113,7 +114,7 @@ Example usage:
|
|
113
114
|
|
114
115
|
```ruby
|
115
116
|
leaf = Tree.leaf
|
116
|
-
node = Tree.node(:value => 'a', :left => Tree.leaf, right => Tree.leaf)
|
117
|
+
node = Tree.node(:value => 'a', :left => Tree.leaf, :right => Tree.leaf)
|
117
118
|
|
118
119
|
leaf.contains?('a')
|
119
120
|
# => false
|
data/lib/typist.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# This is the top level module for the gem, used as a namespace and as a
|
2
2
|
# location for high-level functions.
|
3
3
|
module Typist
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
require 'typist/constructor'
|
5
|
+
require 'typist/data'
|
6
|
+
require 'typist/data_func'
|
7
|
+
require 'typist/error'
|
8
|
+
require 'typist/func'
|
9
|
+
require 'typist/util'
|
9
10
|
|
10
11
|
# Define a new data type.
|
11
12
|
def data(*args, &block)
|
data/lib/typist/data.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Instances of this class may be included like a module.
|
2
2
|
class Typist::Data
|
3
|
-
attr_reader :name, :constructors, :funcs, :block
|
3
|
+
attr_reader :name, :constructors, :funcs, :data_funcs, :block
|
4
4
|
|
5
5
|
# Create a new data type with the given name. The block will be evaluated in
|
6
6
|
# the context of the new instance.
|
@@ -8,6 +8,7 @@ class Typist::Data
|
|
8
8
|
@name = name
|
9
9
|
@constructors = []
|
10
10
|
@funcs = []
|
11
|
+
@data_funcs = []
|
11
12
|
@block = block
|
12
13
|
end
|
13
14
|
|
@@ -21,6 +22,11 @@ class Typist::Data
|
|
21
22
|
funcs << Typist::Func.new(*args, &block)
|
22
23
|
end
|
23
24
|
|
25
|
+
# Define a function whose receiver is the data type.
|
26
|
+
def data_func(*args, &block)
|
27
|
+
data_funcs << Typist::DataFunc.new(*args, &block)
|
28
|
+
end
|
29
|
+
|
24
30
|
# Get the module that is defined.
|
25
31
|
def get_module
|
26
32
|
@module ||= Module.new
|
@@ -33,6 +39,7 @@ class Typist::Data
|
|
33
39
|
instance_eval(&block) unless block.nil?
|
34
40
|
constructors.each { |constructor| constructor.define!(context) }
|
35
41
|
funcs.each { |func| func.define!(context) }
|
42
|
+
data_funcs.each { |func| func.define!(context) }
|
36
43
|
end
|
37
44
|
end
|
38
45
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# A DataFunc is Typist's equivalent of a class method.
|
2
|
+
class Typist::DataFunc
|
3
|
+
attr_reader :name, :block
|
4
|
+
|
5
|
+
# Create a new DataFunc.
|
6
|
+
def initialize(name, &block)
|
7
|
+
@name = name
|
8
|
+
@block = block
|
9
|
+
end
|
10
|
+
|
11
|
+
# Define a DataFunc in the given context.
|
12
|
+
def define!(context)
|
13
|
+
context.define_singleton_method(name, &block)
|
14
|
+
end
|
15
|
+
end
|
data/lib/typist/version.rb
CHANGED
@@ -5,11 +5,11 @@ describe Typist::Constructor do
|
|
5
5
|
subject { described_class.new(:Node, :value, :left, :right) }
|
6
6
|
|
7
7
|
it 'sets the @name instance variable' do
|
8
|
-
subject.name.
|
8
|
+
expect(subject.name).to eq(:Node)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'sets the @vars instance variable' do
|
12
|
-
subject.vars.
|
12
|
+
expect(subject.vars).to eq([:value, :left, :right])
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -17,7 +17,7 @@ describe Typist::Constructor do
|
|
17
17
|
subject { described_class.new(:Leaf) }
|
18
18
|
|
19
19
|
it 'returns a Class' do
|
20
|
-
subject.get_class.
|
20
|
+
expect(subject.get_class).to be_a(Class)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -33,19 +33,19 @@ describe Typist::Constructor do
|
|
33
33
|
}
|
34
34
|
|
35
35
|
it 'has each @var as an accessor' do
|
36
|
-
instance.
|
37
|
-
instance.
|
38
|
-
instance.
|
36
|
+
expect(instance).to respond_to((:arg1))
|
37
|
+
expect(instance).to respond_to((:arg2))
|
38
|
+
expect(instance).to_not respond_to(:arg3)
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'accepts a hash in its initializer which sets instance variables' do
|
42
|
-
instance.instance_variable_get(:@arg1).
|
43
|
-
instance.instance_variable_get(:@arg2).
|
44
|
-
instance.instance_variable_get(:@arg3).
|
42
|
+
expect(instance.instance_variable_get(:@arg1)).to eq('a')
|
43
|
+
expect(instance.instance_variable_get(:@arg2)).to eq('b')
|
44
|
+
expect(instance.instance_variable_get(:@arg3)).to eq('c')
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'includes the given module' do
|
48
|
-
subject.get_class.ancestors.
|
48
|
+
expect(subject.get_class.ancestors).to include(mod)
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -53,9 +53,9 @@ describe Typist::Constructor do
|
|
53
53
|
let(:instance) { mod.test_class(:arg1 => 1, :arg2 => 2) }
|
54
54
|
|
55
55
|
it 'defines a method to create an instance of the defined class' do
|
56
|
-
instance.
|
57
|
-
instance.arg1.
|
58
|
-
instance.arg2.
|
56
|
+
expect(instance).to be_a(mod::TestClass)
|
57
|
+
expect(instance.arg1).to eq(1)
|
58
|
+
expect(instance.arg2).to eq(2)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Typist::DataFunc do
|
4
|
+
describe '#initialize' do
|
5
|
+
let(:name) { :test_func }
|
6
|
+
let(:block) { proc { |x| x.succ } }
|
7
|
+
subject { Typist::DataFunc.new(name, &block) }
|
8
|
+
|
9
|
+
it 'creates a new DataFunc with the given name and block' do
|
10
|
+
expect(subject.name).to eq(name)
|
11
|
+
expect(subject.block.call(1)).to eq(2)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#define!' do
|
16
|
+
let(:name) { :chomp }
|
17
|
+
let(:block) { proc { |str| str.chomp } }
|
18
|
+
let(:mod) { Module.new }
|
19
|
+
subject { Typist::DataFunc.new(name, &block) }
|
20
|
+
|
21
|
+
before { subject.define!(mod) }
|
22
|
+
|
23
|
+
it 'defines its @name on the given module' do
|
24
|
+
expect(mod.chomp("test\n")).to eq('test')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -6,15 +6,15 @@ describe Typist::Data do
|
|
6
6
|
subject { described_class.new(:Test) }
|
7
7
|
|
8
8
|
it 'sets the @name' do
|
9
|
-
subject.name.
|
9
|
+
expect(subject.name).to eq(:Test)
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'sets the @constructors to []' do
|
13
|
-
subject.constructors.
|
13
|
+
expect(subject.constructors).to be_empty
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'sets the @funcs to []' do
|
17
|
-
subject.funcs.
|
17
|
+
expect(subject.funcs).to be_empty
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -34,7 +34,7 @@ describe Typist::Data do
|
|
34
34
|
expect { subject.constructor(:Leaf) }
|
35
35
|
.to change { subject.constructors.length }.by(1)
|
36
36
|
|
37
|
-
subject.constructors.
|
37
|
+
expect(subject.constructors).to be_all { |constructor|
|
38
38
|
constructor.is_a?(Typist::Constructor)
|
39
39
|
}
|
40
40
|
end
|
@@ -43,12 +43,25 @@ describe Typist::Data do
|
|
43
43
|
describe '#func' do
|
44
44
|
subject { described_class.new(:Trie) }
|
45
45
|
|
46
|
-
it 'adds a
|
46
|
+
it 'adds a func' do
|
47
47
|
expect { subject.func(:empty) }
|
48
48
|
.to change { subject.funcs.length }.by(1)
|
49
49
|
|
50
|
-
subject.funcs.
|
51
|
-
|
50
|
+
expect(subject.funcs).to be_all { |func|
|
51
|
+
func.is_a?(Typist::Func)
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#data_func' do
|
57
|
+
subject { described_class.new(:SomeTree) }
|
58
|
+
|
59
|
+
it 'adds a data func' do
|
60
|
+
expect { subject.data_func(:test) { } }
|
61
|
+
.to change { subject.data_funcs.length }.by(1)
|
62
|
+
|
63
|
+
expect(subject.data_funcs).to be_all { |data_func|
|
64
|
+
data_func.is_a?(Typist::DataFunc)
|
52
65
|
}
|
53
66
|
end
|
54
67
|
end
|
@@ -57,7 +70,7 @@ describe Typist::Data do
|
|
57
70
|
subject { described_class.new(:Set) }
|
58
71
|
|
59
72
|
it 'returns a module' do
|
60
|
-
subject.get_module.
|
73
|
+
expect(subject.get_module).to be_a(Module)
|
61
74
|
end
|
62
75
|
end
|
63
76
|
|
@@ -67,6 +80,10 @@ describe Typist::Data do
|
|
67
80
|
constructor :Leaf
|
68
81
|
constructor :Node, :value, :left, :right
|
69
82
|
|
83
|
+
data_func :singleton do |value|
|
84
|
+
Tree.node(:value => value, :left => Tree.leaf, :right => Tree.leaf)
|
85
|
+
end
|
86
|
+
|
70
87
|
func :empty? do
|
71
88
|
match(Tree::Leaf) { true }
|
72
89
|
match(Tree::Node) { false }
|
@@ -116,29 +133,34 @@ describe Typist::Data do
|
|
116
133
|
}
|
117
134
|
|
118
135
|
it 'defines convenience methods' do
|
119
|
-
Tree.
|
120
|
-
Tree.
|
136
|
+
expect(Tree).to respond_to(:node)
|
137
|
+
expect(Tree).to respond_to(:leaf)
|
121
138
|
end
|
122
139
|
|
123
140
|
it 'defines each constructor' do
|
124
|
-
Tree::Node.
|
125
|
-
Tree::Leaf.
|
141
|
+
expect(Tree::Node.ancestors).to include(Tree)
|
142
|
+
expect(Tree::Leaf.ancestors).to include(Tree)
|
143
|
+
|
144
|
+
expect(node.value).to eq(4)
|
145
|
+
expect(node.left).to eq(Tree.leaf)
|
146
|
+
expect(node.right).to eq(Tree.leaf)
|
147
|
+
end
|
126
148
|
|
127
|
-
|
128
|
-
|
129
|
-
|
149
|
+
it 'defines each data function' do
|
150
|
+
expect(Tree.singleton(1))
|
151
|
+
.to eq(Tree.node(:value => 1, :left => Tree.leaf, :right => Tree.leaf))
|
130
152
|
end
|
131
153
|
|
132
154
|
it 'defines functions on the constructors' do
|
133
|
-
leaf.
|
134
|
-
node.
|
155
|
+
expect(leaf).to be_empty
|
156
|
+
expect(node).to_not be_empty
|
135
157
|
|
136
|
-
leaf.contains?(4).
|
137
|
-
node.contains?(4).
|
138
|
-
node.contains?(5).
|
158
|
+
expect(leaf.contains?(4)).to be_false
|
159
|
+
expect(node.contains?(4)).to be_true
|
160
|
+
expect(node.contains?(5)).to be_false
|
139
161
|
|
140
|
-
leaf.size.
|
141
|
-
node.size.
|
162
|
+
expect(leaf.size).to eq(0)
|
163
|
+
expect(node.size).to eq(1)
|
142
164
|
end
|
143
165
|
end
|
144
166
|
end
|
@@ -6,11 +6,11 @@ describe Typist::Func do
|
|
6
6
|
subject { described_class.new(:a_function) }
|
7
7
|
|
8
8
|
it 'sets the @name instance variable to the first argument' do
|
9
|
-
subject.name.
|
9
|
+
expect(subject.name).to eq(:a_function)
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'has no matches intially' do
|
13
|
-
subject.matches.
|
13
|
+
expect(subject.matches).to be_empty
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
@@ -29,12 +29,11 @@ describe Typist::Func do
|
|
29
29
|
before { subject.match(Fixnum) { :it_works } }
|
30
30
|
|
31
31
|
it 'adds that to the @matches hash' do
|
32
|
-
subject.matches[Fixnum].call.
|
32
|
+
expect(subject.matches[Fixnum].call).to eq(:it_works)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
describe '#define!' do
|
37
|
-
|
38
37
|
context 'when an invalid class is matched against' do
|
39
38
|
subject {
|
40
39
|
module BaseModule; end
|
@@ -75,7 +74,7 @@ describe Typist::Func do
|
|
75
74
|
|
76
75
|
context 'when a subclass does match against the function' do
|
77
76
|
it 'evaluates its match' do
|
78
|
-
Matches.new.alpha.
|
77
|
+
expect(Matches.new.alpha).to eq('qt3.14')
|
79
78
|
end
|
80
79
|
end
|
81
80
|
end
|
data/spec/lib/typist_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Typist do
|
4
|
-
it { should be_a Module }
|
5
|
-
|
6
4
|
describe '#data' do
|
7
5
|
before do
|
8
6
|
extend Typist
|
@@ -19,13 +17,13 @@ describe Typist do
|
|
19
17
|
end
|
20
18
|
|
21
19
|
it 'defines a data type' do
|
22
|
-
Boolean.
|
20
|
+
expect(Boolean).to be_a(Module)
|
23
21
|
|
24
|
-
Boolean.false.
|
25
|
-
Boolean.true.
|
22
|
+
expect(Boolean.false).to be_a(Boolean::False)
|
23
|
+
expect(Boolean.true).to be_a(Boolean::True)
|
26
24
|
|
27
|
-
Boolean.false.to_i.
|
28
|
-
Boolean.true.to_i.
|
25
|
+
expect(Boolean.false.to_i).to eq(0)
|
26
|
+
expect(Boolean.true.to_i).to eq(1)
|
29
27
|
end
|
30
28
|
end
|
31
29
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
|
3
|
+
# Submit metrics to code climate.
|
4
|
+
unless ENV['CODECLIMATE_REPO_TOKEN'].nil?
|
5
|
+
require 'codeclimate-test-reporter'
|
6
|
+
CodeClimate::TestReporter.start
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'pry'
|
3
10
|
require 'rspec'
|
4
11
|
require 'typist'
|
5
12
|
|
data/typist.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Hulihan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: codeclimate-test-reporter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Algebraic data types for Ruby
|
70
84
|
email:
|
71
85
|
- hulihan.tom159@gmail.com
|
@@ -81,11 +95,13 @@ files:
|
|
81
95
|
- lib/typist.rb
|
82
96
|
- lib/typist/constructor.rb
|
83
97
|
- lib/typist/data.rb
|
98
|
+
- lib/typist/data_func.rb
|
84
99
|
- lib/typist/error.rb
|
85
100
|
- lib/typist/func.rb
|
86
101
|
- lib/typist/util.rb
|
87
102
|
- lib/typist/version.rb
|
88
103
|
- spec/lib/typist/constructor_spec.rb
|
104
|
+
- spec/lib/typist/data_func_spec.rb
|
89
105
|
- spec/lib/typist/data_spec.rb
|
90
106
|
- spec/lib/typist/func_spec.rb
|
91
107
|
- spec/lib/typist/util_spec.rb
|
@@ -118,6 +134,7 @@ specification_version: 4
|
|
118
134
|
summary: Algebraic data types for Ruby
|
119
135
|
test_files:
|
120
136
|
- spec/lib/typist/constructor_spec.rb
|
137
|
+
- spec/lib/typist/data_func_spec.rb
|
121
138
|
- spec/lib/typist/data_spec.rb
|
122
139
|
- spec/lib/typist/func_spec.rb
|
123
140
|
- spec/lib/typist/util_spec.rb
|