cont 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 493e03fe958a5776f33b1bbd144830a66893bd02e75a6b93fc2dc3b836817a51
4
- data.tar.gz: 250d5cdad63e5cafd2b90e34ff90af5d6d3b903706a4edec0e6b4667f7ff0031
3
+ metadata.gz: adab10aeca75132c8499d155eca42e44d00fdf7b29761625dcf9b7c0165c2b68
4
+ data.tar.gz: 7f3a66c63732fe21ffec879ca170a4e552ccf378c5cb3bfd80c3bf12d5f1dd85
5
5
  SHA512:
6
- metadata.gz: e5cee2b1b33182f7935345da4efadbd4567fd4f89e75f6f07b4400b8dc8292102508500caba9d56504e1ceeb1c1d43badcded4004e524541ac5daf0eaa1e1d3e
7
- data.tar.gz: 68b9aec29911124c3e5e2a28932512ace12bdace81ac6ff5302b575f1bdef30634e2203657418dfd35d2f9403237281ee57befbded131c4a9a153f29e811cbe7
6
+ metadata.gz: 3f70edef9b1d408f5f14e648971aea3bf9fe307e35f489b94caf6228939cf507d7575f3945e3db0c99a37adfe58ff1abda177a3439155ba59132465366361c68
7
+ data.tar.gz: 28eae38504964fb72bc261411b4a4b87dc47e64694f8ea779fccbac1495530546687ef09de3c5b6909529324ec4eb02a096d8475d6f087ee7066a2cdf71a4768
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # Cont Library
1
+ # Cont
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/cont.svg)](https://badge.fury.io/rb/cont)
2
4
 
3
5
  ## Overview
4
6
 
@@ -28,7 +30,6 @@ It takes a block of code and returns the result of that block.
28
30
 
29
31
  ```ruby
30
32
  result = Cont.reset do
31
- # Your code here
32
33
  42
33
34
  end
34
35
  puts result # => 42
@@ -43,11 +44,41 @@ It takes a block of code, which should call a lambda to resume the continuation.
43
44
 
44
45
  ```ruby
45
46
  result = Cont.reset do
46
- Cont.shift do |cont|
47
- cont.call(42) + 1
47
+ Cont.shift do |k|
48
+ k.call(42) + 1
48
49
  end
49
50
  end
50
- puts result # => 42
51
+ puts result # => 43
52
+ ```
53
+
54
+ ### `Cont.reset_at`
55
+
56
+ `Cont.reset_at` limits the continuation to the current block and assigns it a tag.
57
+ It takes a tag and a block of code, allowing you to manage multiple continuation points.
58
+
59
+ #### Example
60
+
61
+ ```ruby
62
+ result = Cont.reset_at(:x) do
63
+ 1 + Cont.shift_at(:x) { |cont| cont.call(2) }
64
+ end
65
+ puts result # => 3
66
+ ```
67
+
68
+ ### `Cont.shift_at`
69
+
70
+ `Cont.shift_at` captures the current continuation associated with a specific tag and allows you to resume it.
71
+ It takes a tag and a block of code, enabling more complex control flow by using multiple continuations.
72
+
73
+ #### Example
74
+
75
+ ```ruby
76
+ result = Cont.reset_at(:x) do
77
+ Cont.shift_at(:x) do |k|
78
+ k.call(42) + 1
79
+ end
80
+ end
81
+ puts result # => 43
51
82
  ```
52
83
 
53
84
  ## Exceptions
@@ -0,0 +1,65 @@
1
+ module MultiPrompt
2
+
3
+ # The 'fiber' library is required for the implementation of continuations.
4
+ require 'fiber'
5
+
6
+ # Exception for handling dead continuation
7
+ class DeadContinuationError < StandardError; end
8
+
9
+ # Exception for handling unexpected statuses
10
+ class UnexpectedStatusError < StandardError; end
11
+
12
+ # Limit the continuation to the current block.
13
+ #
14
+ # @yield [block] The block of code to be run
15
+ # @return [Object] The result of the block.
16
+ def reset_at(tag, &block)
17
+ prompt0_at(tag, &block)
18
+ end
19
+
20
+ # Capture the current continuation.
21
+ #
22
+ # @yield [block] The block of code to be run
23
+ # @return [Object] The result of the block.
24
+ def shift_at(tag, &block)
25
+ control0_at(tag) do |fiber|
26
+ prompt0_at(tag) do
27
+ block.call lambda { |value|
28
+ prompt0_at(tag) do
29
+ raise DeadContinuationError.new unless fiber.alive?
30
+ run_at(nil, fiber, :resume, lambda { value })
31
+ end
32
+ }
33
+ end
34
+ end
35
+ end
36
+
37
+ def run_at(tag, fiber, *args)
38
+ case fiber.resume(*args)
39
+ in :return, value
40
+ value
41
+ in :capture, ^tag, value
42
+ value.call(fiber)
43
+ in :capture, other_tag, value
44
+ run_at(tag, fiber, Fiber.yield(:capture, other_tag, value))
45
+ else
46
+ raise UnexpectedStatusError.new("unexpected status: #{status}")
47
+ end
48
+ end
49
+
50
+ def prompt0_at(tag, &block)
51
+ fiber = Fiber.new do
52
+ Fiber.yield(:return, block.call())
53
+ end
54
+ run_at(tag, fiber)
55
+ end
56
+
57
+ def control0_at(tag, &block)
58
+ status, f = Fiber.yield(:capture, tag, block)
59
+ raise UnexpectedStatusError.new("unexpected status: #{status}") \
60
+ unless status == :resume
61
+ f.call()
62
+ end
63
+
64
+ module_function :reset_at, :shift_at, :run_at, :prompt0_at, :control0_at
65
+ end
@@ -13,7 +13,7 @@ module SinglePrompt
13
13
  #
14
14
  # @yield [block] The block of code to be run
15
15
  # @return [Object] The result of the block.
16
- def self.reset(&block)
16
+ def reset(&block)
17
17
  prompt0(&block)
18
18
  end
19
19
 
@@ -21,7 +21,7 @@ module SinglePrompt
21
21
  #
22
22
  # @yield [block] The block of code to be run
23
23
  # @return [Object] The result of the block.
24
- def self.shift(&block)
24
+ def shift(&block)
25
25
  control0 do |fiber|
26
26
  prompt0 do
27
27
  block.call lambda { |value|
@@ -34,31 +34,30 @@ module SinglePrompt
34
34
  end
35
35
  end
36
36
 
37
- private
38
-
39
- def self.run(fiber, *args)
40
- status, value = fiber.resume(*args)
41
- case status
42
- when :return
37
+ def run(fiber, *args)
38
+ case fiber.resume(*args)
39
+ in :return, value
43
40
  value
44
- when :capture
41
+ in :capture, value
45
42
  value.call(fiber)
46
43
  else
47
44
  raise UnexpectedStatusError.new("unexpected status: #{status}")
48
45
  end
49
46
  end
50
47
 
51
- def self.prompt0(&block)
48
+ def prompt0(&block)
52
49
  fiber = Fiber.new do
53
50
  Fiber.yield(:return, block.call())
54
51
  end
55
52
  run(fiber)
56
53
  end
57
54
 
58
- def self.control0(&block)
55
+ def control0(&block)
59
56
  status, f = Fiber.yield(:capture, block)
60
57
  raise UnexpectedStatusError.new("unexpected status: #{status}") \
61
58
  unless status == :resume
62
59
  f.call()
63
60
  end
61
+
62
+ module_function :reset, :shift, :run, :prompt0, :control0
64
63
  end
data/lib/cont/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cont
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/lib/cont.rb CHANGED
@@ -20,7 +20,11 @@
20
20
  # This software is released under the MIT License.
21
21
 
22
22
  require_relative 'cont/single_prompt'
23
+ require_relative 'cont/multi_prompt'
23
24
 
24
25
  module Cont
25
26
  include SinglePrompt
27
+ include MultiPrompt
28
+ module_function :reset, :shift, :run, :prompt0, :control0
29
+ module_function :reset_at, :shift_at, :run_at, :prompt0_at, :control0_at
26
30
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cont
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaya Taniguchi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-09 00:00:00.000000000 Z
11
+ date: 2024-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.10'
19
+ version: '5.23'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 5.23.1
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '3.10'
29
+ version: '5.23'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.23.1
27
33
  description: |
28
34
  The Cont module provides methods for working with continuations.
29
35
  Continuations are a way to save the execution state of a program
@@ -47,6 +53,7 @@ files:
47
53
  - LICENSE.txt
48
54
  - README.md
49
55
  - lib/cont.rb
56
+ - lib/cont/multi_prompt.rb
50
57
  - lib/cont/single_prompt.rb
51
58
  - lib/cont/version.rb
52
59
  homepage: https://github.com/tani/ruby-cont
@@ -68,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
75
  - !ruby/object:Gem::Version
69
76
  version: '0'
70
77
  requirements: []
71
- rubygems_version: 3.3.25
78
+ rubygems_version: 3.5.9
72
79
  signing_key:
73
80
  specification_version: 4
74
81
  summary: Cont provides methods for working with continuation