ruff 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,10 +6,23 @@ require 'securerandom'
6
6
 
7
7
  module Ruff
8
8
  class << self
9
+ # is alias for `Effect.new`
10
+ # @see Effect.initialize Effect.initialize
11
+ #
12
+ # @example
13
+ # Log = Ruff.instance # === Ruff::Effect.new
9
14
  def instance
10
15
  Effect.new
11
16
  end
12
17
 
18
+ # is alias for `Handler.new`
19
+ # @see Handler.initialize Handler.initialize
20
+ #
21
+ # @example
22
+ # log_handler = Ruff.handler.on(Log){|msg, k|
23
+ # puts "Logger: #{msg}"
24
+ # k[]
25
+ # }
13
26
  def handler
14
27
  Handler.new
15
28
  end
@@ -1,12 +1,25 @@
1
1
  module Ruff
2
+ # This class provides an effect instance.
2
3
  class Effect
3
- attr_accessor :id
4
+ # Each instance must be unique so they have unique id with UUID
5
+ attr_reader :id
6
+
7
+ # instaciates an effect setting `id`.
8
+ # @return [Effect<Arg, Ret>]
9
+ # @example
10
+ # Log = Effect.new #==> it _might_ be Effect<string, nil>
4
11
  def initialize
5
12
  @id = SecureRandom.uuid
13
+ @id.freeze
6
14
  end
7
15
 
16
+ # sends an effect ID and its arguments to a nearmost handler.
17
+ # @param [Arg] a of the object `Effect<Arg, Ret>`
18
+ # @return [Ret] of the object `Effect<Arg, Ret>`
19
+ # @example
20
+ # Log.perform "hello"
8
21
  def perform(*a)
9
- return Fiber.yield Eff.new(@id, a)
22
+ return Fiber.yield Throws::Eff.new(@id, a)
10
23
  end
11
24
  end
12
25
  end
@@ -1,32 +1,72 @@
1
1
  module Ruff
2
+ # In algebraic effects, handler is an first-class object.
2
3
  class Handler
4
+ # makes a new handler, internally having fresh empty hash.
5
+ # This is a effect-handler store and when handliong it is looked up.
6
+ # @example
7
+ # handler = Handler.new
3
8
  def initialize
4
9
  @handlers = Hash.new
5
10
  end
6
11
 
12
+ # sets effec handler `&prc` for `eff`
13
+ #
14
+ # @param [Effect<Arg, Ret>] eff
15
+ # the effect instance to be handled
16
+ # @param [Proc<Arg, Ret => A>] prc
17
+ # a handler to handle `eff`;
18
+ # last argument of `&prc` is *continuation*, proc object
19
+ # to go back to the handled computation.
20
+ # @return [Handler{Effect<Arg, Ret>, e}] itself updated with handling `Effect<Arg, Ret>`
21
+ #
22
+ # @example
23
+ # handler.on(Log) {|msg, k|
24
+ # puts "Logger: #{msg}"
25
+ # k[]
26
+ # }
7
27
  def on(eff, &prc)
8
28
  @handlers[eff.id] = prc
9
29
 
10
30
  self
11
31
  end
12
32
 
33
+ # @param [Proc<(), T>]
34
+ # @return [T]
35
+ #
36
+ # handles the computation.
37
+ #
38
+ # @example
39
+ # handler.run {
40
+ # Log.perform "hello"
41
+ # }
42
+ #
43
+ # @example `handler` can be layered.
44
+ # handler.run {
45
+ # Handler.new
46
+ # .on(Double){|v, k|
47
+ # k[v * v]
48
+ # }.run {
49
+ # v = Double.perform 3
50
+ # Log.perform 3
51
+ # }
52
+ # }
13
53
  def run(&prc)
14
54
  co = Fiber.new &prc
15
55
  continue = nil
16
56
  rehandles = nil
17
57
 
18
58
  handle = ->(r) {
19
- if r.is_a? Eff
59
+ if r.is_a? Throws::Eff
20
60
  if effh = @handlers[r.id]
21
61
  effh[continue, *r.args]
22
62
  else
23
- Fiber.yield (Resend.new r, continue)
63
+ Fiber.yield (Throws::Resend.new r, continue)
24
64
  end
25
- elsif r.is_a? Resend
65
+ elsif r.is_a? Throws::Resend
26
66
  if effh = @handlers[r.eff.id]
27
67
  effh[rehandles[r.k], *r.eff.args]
28
68
  else
29
- Fiber.yield (Resend.new r, rehandles[r.k])
69
+ Fiber.yield (Throws::Resend.new r, rehandles[r.k])
30
70
  end
31
71
  else
32
72
  r
@@ -43,6 +83,10 @@ module Ruff
43
83
  newh.add_handler id, h
44
84
  }
45
85
 
86
+ class << newh
87
+ undef add_handler
88
+ end
89
+
46
90
  ->(*args) {
47
91
  continue[
48
92
  newh.run {
@@ -1,15 +1,39 @@
1
1
  module Ruff
2
- class Eff
3
- attr_accessor :id, :args
4
- def initialize(id, args)
5
- @id = id; @args = args
2
+ module Throws
3
+ # `Eff` is internal object.
4
+ #
5
+ # They make effects encapsulate with ID and arguments to be sent to the handler.
6
+ class Eff
7
+
8
+ # makes the object unique.
9
+ attr_reader :id
10
+
11
+ # passes to a handler which can catch the effect.
12
+ attr_reader :args
13
+
14
+ # creates a new object with `id` and `args`.
15
+ def initialize(id, args)
16
+ @id = id; @args = args
17
+ end
6
18
  end
7
19
  end
8
20
 
9
- class Resend
10
- attr_accessor :eff, :k
11
- def initialize(eff, k)
12
- @eff = eff; @k = k
21
+ module Throws
22
+ # `Resend` is internal object like `Eff`.
23
+ #
24
+ # It is used when an effect is unable to be handled and should be thrown to the outer handler.
25
+ class Resend
26
+
27
+ #is abstracted effect (such as `Eff` or (re)thrown `Resend`).
28
+ attr_reader :eff
29
+
30
+ # is a continuation of `eff` thrown context.
31
+ attr_reader :k
32
+
33
+ # creates a new object with `eff` and `k`.
34
+ def initialize(eff, k)
35
+ @eff = eff; @k = k
36
+ end
13
37
  end
14
38
  end
15
39
  end
@@ -0,0 +1,5 @@
1
+ # // This file is passed to CPP
2
+ #include "../../version.h"
3
+ module Ruff
4
+ VERSION = RUFF_VERSION
5
+ end
@@ -1,3 +1,3 @@
1
1
  module Ruff
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -3,7 +3,7 @@ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require "ruff/version"
5
5
 
6
- Gem::Specification.new do |spec|
6
+ Gem::Specification.new{|spec|
7
7
  spec.name = "ruff"
8
8
  spec.version = Ruff::VERSION
9
9
  spec.authors = ["nymphium"]
@@ -13,14 +13,17 @@ Gem::Specification.new do |spec|
13
13
  spec.description = %q{ONE-SHOT Algebraic Effects for Ruby!}
14
14
  spec.homepage = "https://github.com/nymphium/ruff"
15
15
  spec.license = "MIT"
16
+
16
17
 
17
18
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
19
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
20
  end
20
- spec.bindir = "exe"
21
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
21
  spec.require_paths = ["lib"]
23
22
 
24
23
  spec.add_development_dependency "bundler", "~> 2.0"
25
24
  spec.add_development_dependency "rake", "~> 10.0"
26
- end
25
+
26
+ spec.metadata = {
27
+ "documentation_url" => "https://nymphium.github.io/ruff"
28
+ }
29
+ }
@@ -0,0 +1 @@
1
+ #define RUFF_VERSION "0.0.5"
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: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - nymphium
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-06 00:00:00.000000000 Z
11
+ date: 2019-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -51,16 +51,39 @@ files:
51
51
  - LICENSE
52
52
  - README.md
53
53
  - Rakefile
54
+ - docs/Ruff.html
55
+ - docs/Ruff/Effect.html
56
+ - docs/Ruff/Handler.html
57
+ - docs/Ruff/Throws.html
58
+ - docs/Ruff/Throws/Eff.html
59
+ - docs/Ruff/Throws/Resend.html
60
+ - docs/_index.html
61
+ - docs/class_list.html
62
+ - docs/css/common.css
63
+ - docs/css/full_list.css
64
+ - docs/css/style.css
65
+ - docs/file.README.html
66
+ - docs/file_list.html
67
+ - docs/frames.html
68
+ - docs/index.html
69
+ - docs/js/app.js
70
+ - docs/js/full_list.js
71
+ - docs/js/jquery.js
72
+ - docs/method_list.html
73
+ - docs/top-level-namespace.html
54
74
  - lib/ruff.rb
55
75
  - lib/ruff/effect.rb
56
76
  - lib/ruff/handler.rb
57
77
  - lib/ruff/objects.rb
78
+ - lib/ruff/version.cpp.rb
58
79
  - lib/ruff/version.rb
59
80
  - ruff.gemspec
81
+ - version.h
60
82
  homepage: https://github.com/nymphium/ruff
61
83
  licenses:
62
84
  - MIT
63
- metadata: {}
85
+ metadata:
86
+ documentation_url: https://nymphium.github.io/ruff
64
87
  post_install_message:
65
88
  rdoc_options: []
66
89
  require_paths: