ruff 1.4.0 → 2.0.0
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/.rubocop.yml +1 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +16 -12
- data/README.md +35 -58
- data/Rakefile +2 -1
- data/docs/Ruff.html +7 -7
- data/docs/Ruff/Effect.html +165 -23
- data/docs/Ruff/Handler.html +45 -50
- data/docs/Ruff/Standard.html +6 -6
- data/docs/Ruff/Standard/Async.html +26 -26
- data/docs/Ruff/Standard/Async/Instance.html +8 -8
- data/docs/Ruff/Standard/Call1cc.html +6 -6
- data/docs/Ruff/Standard/CurrentTime.html +6 -6
- data/docs/Ruff/Standard/CurrentTime/Instance.html +7 -7
- data/docs/Ruff/Standard/Defer.html +6 -6
- data/docs/Ruff/Standard/Defer/Instance.html +6 -6
- data/docs/Ruff/Standard/MeasureTime.html +6 -6
- data/docs/Ruff/Standard/MeasureTime/Instance.html +8 -8
- data/docs/Ruff/Standard/State.html +6 -6
- data/docs/Ruff/Standard/State/Instance.html +6 -6
- data/docs/Ruff/Throws.html +6 -11
- data/docs/Ruff/Throws/Eff.html +6 -6
- data/docs/Ruff/Throws/Resend.html +6 -6
- data/docs/_index.html +7 -7
- data/docs/class_list.html +2 -2
- data/docs/css/style.css +2 -2
- data/docs/file.README.html +39 -56
- data/docs/file_list.html +2 -2
- data/docs/frames.html +2 -2
- data/docs/index.html +39 -56
- data/docs/js/app.js +14 -3
- data/docs/method_list.html +71 -63
- data/docs/top-level-namespace.html +6 -6
- data/lib/ruff/effect.rb +32 -3
- data/lib/ruff/handler.rb +43 -18
- data/lib/ruff/standard/async.rb +10 -7
- data/lib/ruff/standard/current_time.rb +1 -1
- data/lib/ruff/standard/measure_time.rb +2 -2
- data/lib/ruff/version.rb +1 -1
- data/version +1 -1
- metadata +3 -3
@@ -6,15 +6,15 @@
|
|
6
6
|
<title>
|
7
7
|
Top Level Namespace
|
8
8
|
|
9
|
-
— Ruff 1.
|
9
|
+
— Ruff 1.4.0 Documentation
|
10
10
|
|
11
11
|
</title>
|
12
12
|
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css"
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" />
|
14
14
|
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css"
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" />
|
16
16
|
|
17
|
-
<script type="text/javascript"
|
17
|
+
<script type="text/javascript">
|
18
18
|
pathId = "";
|
19
19
|
relpath = '';
|
20
20
|
</script>
|
@@ -100,9 +100,9 @@
|
|
100
100
|
</div>
|
101
101
|
|
102
102
|
<div id="footer">
|
103
|
-
Generated on
|
103
|
+
Generated on Thu Jan 2 19:46:22 2020 by
|
104
104
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
105
|
-
0.9.
|
105
|
+
0.9.22 (ruby-2.6.5).
|
106
106
|
</div>
|
107
107
|
|
108
108
|
</div>
|
data/lib/ruff/effect.rb
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
# This class provides an effect instance.
|
4
4
|
class Ruff::Effect
|
5
|
-
# Each instance must be unique so they have unique id with
|
5
|
+
# Each instance must be unique so they have unique id with an annonymous class instance.
|
6
|
+
#
|
7
|
+
# The class instance may have subtyping relation.
|
8
|
+
# @see <<
|
6
9
|
attr_reader :id
|
7
10
|
|
8
11
|
# instaciates an effect setting `id`.
|
@@ -10,13 +13,39 @@ class Ruff::Effect
|
|
10
13
|
# @example
|
11
14
|
# Log = Effect.new #==> it _might_ be Effect<string, nil>
|
12
15
|
def initialize
|
13
|
-
@id =
|
14
|
-
|
16
|
+
@id = Class.new.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# instanciates an effect, which has an relation `self <: parent`
|
20
|
+
# from the subtyping of `id` object.
|
21
|
+
#
|
22
|
+
# @param [Effect<Arg, Ret>] parent
|
23
|
+
# @return [Effect<Arg, Ret>] with an relation `it <: parent`
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# Exception = Ruff::Effect.new
|
27
|
+
# RuntimeException = Ruff::Effect << Exception
|
28
|
+
#
|
29
|
+
# Ruff::Handler.new
|
30
|
+
# .on(Exception){
|
31
|
+
# puts "catch"
|
32
|
+
# }
|
33
|
+
# .run {
|
34
|
+
# RuntimeException.perform
|
35
|
+
# }
|
36
|
+
# # ==> prints "catch"
|
37
|
+
def self.<<(parent)
|
38
|
+
inst = new
|
39
|
+
parent_id = parent.instance_variable_get('@id')
|
40
|
+
inst.instance_variable_set('@id', (Class.new parent_id.class).new)
|
41
|
+
inst
|
15
42
|
end
|
16
43
|
|
17
44
|
# sends an effect ID and its arguments to a nearmost handler.
|
45
|
+
#
|
18
46
|
# @param [Arg] a of the object `Effect<Arg, Ret>`
|
19
47
|
# @return [Ret] of the object `Effect<Arg, Ret>`
|
48
|
+
#
|
20
49
|
# @example
|
21
50
|
# Log.perform "hello"
|
22
51
|
def perform(*a)
|
data/lib/ruff/handler.rb
CHANGED
@@ -2,17 +2,41 @@
|
|
2
2
|
|
3
3
|
# In algebraic effects, handler is an first-class object.
|
4
4
|
class Ruff::Handler
|
5
|
-
include Ruff::Throws
|
6
|
-
|
7
5
|
# makes a new handler, internally having fresh empty hash.
|
8
6
|
#
|
9
7
|
# This is a effect-handler store and when handliong it is looked up.
|
10
|
-
# Value handler is set
|
11
|
-
|
8
|
+
# Value handler is set an identity function to by default.
|
9
|
+
|
10
|
+
class Store
|
11
|
+
# is a private class to manage registered handlers
|
12
|
+
def initialize
|
13
|
+
@handler = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def []=(r, e)
|
17
|
+
@handler[r.id] = e
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](eff)
|
21
|
+
# get a set {(eff', f) | forall (eff', f) in store. eff <: eff'}
|
22
|
+
fns = @handler.filter do |effky, _fun|
|
23
|
+
eff.id.is_a? effky.class
|
24
|
+
end
|
25
|
+
|
26
|
+
# pick a function with *smallest* effect class
|
27
|
+
return fns.min_by { |effky, _| effky.class }[1] unless fns.empty?
|
28
|
+
|
29
|
+
# if found nothing
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private_constant :Store
|
35
|
+
|
12
36
|
# @example
|
13
37
|
# handler = Handler.new
|
14
38
|
def initialize
|
15
|
-
@handlers =
|
39
|
+
@handlers = Store.new
|
16
40
|
@valh = ->(x) { x }
|
17
41
|
end
|
18
42
|
|
@@ -56,7 +80,10 @@ class Ruff::Handler
|
|
56
80
|
self
|
57
81
|
end
|
58
82
|
|
59
|
-
# sets effec handler `&fun` for `eff`
|
83
|
+
# sets or updates effec handler `&fun` for `eff`
|
84
|
+
#
|
85
|
+
# Note that `eff` can be a supertype of an effect to be caught.
|
86
|
+
# @see Effect.<<
|
60
87
|
#
|
61
88
|
# @param [Effect<Arg, Ret>] eff
|
62
89
|
# the effect instance to be handled
|
@@ -73,7 +100,7 @@ class Ruff::Handler
|
|
73
100
|
# k[]
|
74
101
|
# }
|
75
102
|
def on(eff, &fun)
|
76
|
-
@handlers[eff
|
103
|
+
@handlers[eff] = fun
|
77
104
|
|
78
105
|
self
|
79
106
|
end
|
@@ -107,13 +134,13 @@ class Ruff::Handler
|
|
107
134
|
continue(co).call(nil)
|
108
135
|
end
|
109
136
|
|
110
|
-
|
137
|
+
protected
|
138
|
+
|
139
|
+
# receives `handlers` as new handlers.
|
111
140
|
def handlers=(handlers)
|
112
141
|
@handlers = handlers.dup
|
113
142
|
end
|
114
143
|
|
115
|
-
private
|
116
|
-
|
117
144
|
def continue(co)
|
118
145
|
->(*arg) { handle(co, co.resume(*arg)) }
|
119
146
|
end
|
@@ -121,20 +148,20 @@ class Ruff::Handler
|
|
121
148
|
# rubocop:disable Metrics/AbcSize
|
122
149
|
def handle(co, r)
|
123
150
|
case r
|
124
|
-
when Eff
|
125
|
-
if (effh = @handlers[r
|
151
|
+
when Ruff::Throws::Eff
|
152
|
+
if (effh = @handlers[r])
|
126
153
|
effh[continue(co), *r.args]
|
127
154
|
else
|
128
|
-
Fiber.yield Resend.new(r, continue(co))
|
155
|
+
Fiber.yield Ruff::Throws::Resend.new(r, continue(co))
|
129
156
|
end
|
130
|
-
when Resend then
|
157
|
+
when Ruff::Throws::Resend then
|
131
158
|
eff = r.eff
|
132
159
|
next_k = rehandles(co, r.k)
|
133
160
|
|
134
|
-
if (effh = @handlers[eff
|
161
|
+
if (effh = @handlers[eff])
|
135
162
|
effh.call(next_k, *eff.args)
|
136
163
|
else
|
137
|
-
Fiber.yield Resend.new(eff, next_k)
|
164
|
+
Fiber.yield Ruff::Throws::Resend.new(eff, next_k)
|
138
165
|
end
|
139
166
|
else
|
140
167
|
@valh.call(r)
|
@@ -153,6 +180,4 @@ class Ruff::Handler
|
|
153
180
|
.run { k.call(*args) }
|
154
181
|
}
|
155
182
|
end
|
156
|
-
|
157
|
-
private :handlers=
|
158
183
|
end
|
data/lib/ruff/standard/async.rb
CHANGED
@@ -89,7 +89,7 @@ module Ruff::Standard::Async
|
|
89
89
|
@eff.await.perform p
|
90
90
|
end
|
91
91
|
|
92
|
-
# @method with
|
92
|
+
# @method with(&th)
|
93
93
|
# @param [Proc<(), _A!{Async.async, Async.yield, Async.await, e}>] th
|
94
94
|
# is a thunk returning `_A` with te possibility to invoke effects,
|
95
95
|
# including `Async.async` , `Async.yield` and `Async.await` .
|
@@ -108,8 +108,8 @@ module Ruff::Standard::Async
|
|
108
108
|
# rubocop:disable Metrics/AbcSize
|
109
109
|
# rubocop:disable Metrics/BlockLength
|
110
110
|
define_method :fork do |pr, th|
|
111
|
-
Ruff.
|
112
|
-
|
111
|
+
h = Ruff::Handler.new
|
112
|
+
h.to do |v|
|
113
113
|
pp = pr.get
|
114
114
|
l = case pp
|
115
115
|
when Waiting then pp.get
|
@@ -123,16 +123,18 @@ module Ruff::Standard::Async
|
|
123
123
|
pr.set(Done.new(v))
|
124
124
|
@q.dequeue
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
|
+
h.on(@eff.async) do |k, f|
|
127
128
|
pr_ = Util::Ref.new(Waiting.new([]))
|
128
129
|
@q.enqueue(-> { k[pr_] })
|
129
130
|
fork(pr_, f)
|
130
131
|
end
|
131
|
-
|
132
|
+
h.on(@eff.yield) do |k|
|
132
133
|
@q.enqueue(-> { k[] })
|
133
134
|
@q.dequeue.call
|
134
135
|
end
|
135
|
-
|
136
|
+
|
137
|
+
h.on(@eff.await) do |k, ppr|
|
136
138
|
pp = ppr.get
|
137
139
|
|
138
140
|
return case pp
|
@@ -142,7 +144,8 @@ module Ruff::Standard::Async
|
|
142
144
|
@q.dequeue.call
|
143
145
|
end
|
144
146
|
end
|
145
|
-
|
147
|
+
|
148
|
+
h.run { th[] }
|
146
149
|
end
|
147
150
|
# rubocop:enable Metrics/BlockLength
|
148
151
|
# rubocop:enable Metrics/AbcSize
|
@@ -30,7 +30,7 @@ module Ruff::Standard::CurrentTime
|
|
30
30
|
# returns `A` , without modification by value handler.
|
31
31
|
# But it still has the possibility to invoke effects(`e`).
|
32
32
|
def with(&th)
|
33
|
-
|
33
|
+
@handler.run(&th)
|
34
34
|
end
|
35
35
|
|
36
36
|
# You can reimplement the handler using this effect instance.
|
@@ -22,13 +22,13 @@ module Ruff::Standard::MeasureTime
|
|
22
22
|
def initialize
|
23
23
|
@eff = Ruff.instance
|
24
24
|
@handler = Ruff.handler
|
25
|
-
|
25
|
+
@handler.on(@eff) do |k, label|
|
26
26
|
t1 = Time.now
|
27
27
|
result = k[]
|
28
28
|
t2 = Time.now
|
29
29
|
result + [{ label: label, time: t2 - t1 }]
|
30
30
|
end
|
31
|
-
|
31
|
+
@handler.to { |x| [x] }
|
32
32
|
end
|
33
33
|
|
34
34
|
# is a smart method to invoke the effect operation.
|
data/lib/ruff/version.rb
CHANGED
data/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nymphium
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: '0'
|
128
128
|
requirements: []
|
129
|
-
rubygems_version: 3.
|
129
|
+
rubygems_version: 3.1.2
|
130
130
|
signing_key:
|
131
131
|
specification_version: 4
|
132
132
|
summary: ONE-SHOT Algebraic Effects for Ruby!
|