return_bang 1.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.
data.tar.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ 9L�C��M�}
2
+ ߁Z�z��ܦ/⊢V��U�^�׭����בlRg�-�$��6���)�G(�s�i�
data/.autotest ADDED
@@ -0,0 +1,8 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ Autotest.add_hook :initialize do |at|
6
+ at.testlib = 'minitest/autorun'
7
+ end
8
+
data/.gemtest ADDED
File without changes
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ === 1.0 / 2011-12-20
2
+
3
+ * Major enhancements
4
+ * Birthday!
5
+
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.rdoc
5
+ Rakefile
6
+ lib/return_bang.rb
7
+ lib/return_bang/everywhere.rb
8
+ test/test_return_bang.rb
data/README.rdoc ADDED
@@ -0,0 +1,84 @@
1
+ = return_bang
2
+
3
+ home :: https://github.com/drbrain/return_bang
4
+ rdoc :: http://docs.seattlerb.org/return_bang
5
+ bugs :: https://github.com/drbrain/return_bang/issues
6
+
7
+ == Description
8
+
9
+ return_bang implements non-local exits from methods. Use return_bang to exit
10
+ back to a processing loop from deeply nested code, or just to confound your
11
+ enemies *and* your friends! What could possibly go wrong?
12
+
13
+ == Features
14
+
15
+ * Implements non-local exits for methods
16
+ * Nestable
17
+ * Named and stack-based exit points, go exactly where you need to be
18
+ * Ignores pesky ensure blocks for when you really, really need to return
19
+
20
+ == Synopsis
21
+
22
+ require 'return_bang/everywhere'
23
+
24
+ def some_method
25
+ deeply_nested
26
+ # never reached
27
+ end
28
+
29
+ def deeply_nested
30
+ return!
31
+ end
32
+
33
+ return_here do
34
+ some_method
35
+ end
36
+ # resumes here
37
+
38
+ == Testimonials
39
+
40
+ "you'll wind up with your cock in /dev/null somehow" -- slyphon
41
+
42
+ "Haha! Right! This skips ensure… SO EVIL‼‼" -- drbrain
43
+
44
+ "This is so evil that 6 def test_… have turned into: 16 tests, 65 assertions,
45
+ 18 failures, 7 errors" -- drbrain
46
+
47
+ == Install
48
+
49
+ sudo gem install return_bang
50
+
51
+ == Developers
52
+
53
+ After checking out the source, run:
54
+
55
+ $ rake newb
56
+
57
+ This task will install any missing dependencies, run the tests/specs,
58
+ and generate the RDoc.
59
+
60
+ == License
61
+
62
+ (The MIT License)
63
+
64
+ Copyright (c) Eric Hodel
65
+
66
+ Permission is hereby granted, free of charge, to any person obtaining
67
+ a copy of this software and associated documentation files (the
68
+ 'Software'), to deal in the Software without restriction, including
69
+ without limitation the rights to use, copy, modify, merge, publish,
70
+ distribute, sublicense, and/or sell copies of the Software, and to
71
+ permit persons to whom the Software is furnished to do so, subject to
72
+ the following conditions:
73
+
74
+ The above copyright notice and this permission notice shall be
75
+ included in all copies or substantial portions of the Software.
76
+
77
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
78
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
79
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
80
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
81
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
82
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
83
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
84
+
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.plugin :minitest
7
+ Hoe.plugin :git
8
+
9
+ Hoe.spec 'return_bang' do
10
+ developer 'Eric Hodel', 'drbrain@segment7.net'
11
+
12
+ rdoc_locations << 'docs.seattlerb.org:/data/www/docs.seattlerb.org/return_bang/'
13
+
14
+ self.readme_file = 'README.rdoc'
15
+ self.extra_rdoc_files << 'README.rdoc'
16
+ end
17
+
18
+ # vim: syntax=ruby
@@ -0,0 +1,148 @@
1
+ begin
2
+ require 'continuation'
3
+ rescue LoadError
4
+ # in 1.8 it's built-in
5
+ end
6
+
7
+ ##
8
+ # ReturnBang is allows you to perform non-local exits from your methods. One
9
+ # potential use of this is in a web framework so that a framework-provided
10
+ # utility methods can jump directly back to the request loop.
11
+ #
12
+ # return_here is used to designate where execution should be resumed. Return
13
+ # points may be arbitrarily nested. #return! resumes at the previous resume
14
+ # point, #return_to returns to a named return point.
15
+ #
16
+ # require 'return_bang' gives you a module you may include only in your
17
+ # application or library code. require 'return_bang/everywhere' includes
18
+ # ReturnBang in Object, so it is only recommended for application code use.
19
+ #
20
+ # Example:
21
+ #
22
+ # include ReturnBang
23
+ #
24
+ # def framework_loop
25
+ # loop do
26
+ # # setup code
27
+ #
28
+ # return_here do
29
+ # user_code
30
+ # end
31
+ #
32
+ # # resume execution here
33
+ # end
34
+ # end
35
+ #
36
+ # def render_error_and_return message
37
+ # # generate error
38
+ #
39
+ # return!
40
+ # end
41
+ #
42
+ # def user_code
43
+ # user_utility_method
44
+ # # these lines never reached
45
+ # # ...
46
+ # end
47
+ #
48
+ # def user_utility_method
49
+ # render_error_and_return "blah" if some_condition
50
+ # # these lines never reached
51
+ # # ...
52
+ # end
53
+
54
+ module ReturnBang
55
+
56
+ VERSION = '1.0'
57
+
58
+ ##
59
+ # Raised when attempting to return! when you haven't registered a location
60
+ # to return to, or are trying to return to a named point that wasn't
61
+ # registered.
62
+
63
+ class NonLocalJumpError < StandardError
64
+ end
65
+
66
+ def _return_bang_names # :nodoc:
67
+ Thread.current[:return_bang_names] ||= {}
68
+ end
69
+
70
+ if {}.respond_to? :key then # 1.9
71
+ def _return_bang_pop # :nodoc:
72
+ return_point = _return_bang_stack.pop
73
+
74
+ _return_bang_names.delete _return_bang_names.key _return_bang_stack.length
75
+
76
+ return_point
77
+ end
78
+ else # 1.8
79
+ def _return_bang_pop # :nodoc:
80
+ return_point = _return_bang_stack.pop
81
+ value = _return_bang_stack.length
82
+
83
+ _return_bang_names.delete _return_bang_names.index value
84
+
85
+ return_point
86
+ end
87
+ end
88
+
89
+ def _return_bang_stack # :nodoc:
90
+ Thread.current[:return_bang_stack] ||= []
91
+ end
92
+
93
+ ##
94
+ # Returns to the last return point in the stack. If no return points have
95
+ # been registered a NonLocalJumpError is raised. +value+ is returned at the
96
+ # registered return point.
97
+
98
+ def return! value = nil
99
+ raise NonLocalJumpError, 'nowhere to return to' if
100
+ _return_bang_stack.empty?
101
+
102
+ _return_bang_pop.call value
103
+ end
104
+
105
+ ##
106
+ # Registers a return point to jump back to. If a +name+ is given return_to
107
+ # can jump here.
108
+
109
+ def return_here name = nil
110
+ raise ArgumentError, "#{name} is already registered as a return point" if
111
+ _return_bang_names.include? name
112
+
113
+ value = callcc do |cc|
114
+ _return_bang_names[name] = _return_bang_stack.length if name
115
+ _return_bang_stack.push cc
116
+
117
+ begin
118
+ yield
119
+ ensure
120
+ _return_bang_pop
121
+ end
122
+ end
123
+
124
+ # here is where the magic happens
125
+ unwind_to = Thread.current[:unwind_to]
126
+
127
+ return! value if unwind_to and _return_bang_stack.length > unwind_to
128
+
129
+ return value
130
+ end
131
+
132
+ ##
133
+ # Returns to the return point +name+. +value+ is returned at the registered
134
+ # return point.
135
+
136
+ def return_to name, value = nil
137
+ unwind_to = _return_bang_names.delete name
138
+
139
+ raise NonLocalJumpError, "return point :nonexistent was not set" unless
140
+ unwind_to
141
+
142
+ Thread.current[:unwind_to] = unwind_to
143
+
144
+ return! value
145
+ end
146
+
147
+ end
148
+
@@ -0,0 +1,7 @@
1
+ require 'return_bang'
2
+
3
+ ##
4
+ # require 'return_bang/kernel' adds #return! to all objects
5
+
6
+ include ReturnBang
7
+
@@ -0,0 +1,83 @@
1
+ require 'minitest/autorun'
2
+ require 'return_bang'
3
+
4
+ class TestReturnBang < MiniTest::Unit::TestCase
5
+
6
+ include ReturnBang
7
+
8
+ def setup
9
+ @after_a = false
10
+ @after_e = false
11
+ end
12
+
13
+ def teardown
14
+ assert_empty _return_bang_stack
15
+ assert_empty _return_bang_names
16
+ end
17
+
18
+ def test_return_bang_no_return_here
19
+ e = assert_raises NonLocalJumpError do
20
+ return!
21
+ end
22
+
23
+ assert_equal 'nowhere to return to', e.message
24
+ end
25
+
26
+ def test_return_here
27
+ result = return_here do a end
28
+
29
+ refute @after_a, 'return! did not skip after_a'
30
+
31
+ assert_equal 42, result
32
+ end
33
+
34
+ def test_return_here_name
35
+ result = return_here :name do d end
36
+
37
+ refute @after_e, 'return_to did not skip after_e'
38
+
39
+ assert_equal 43, result
40
+ end
41
+
42
+ def test_return_here_name_no_return_bang
43
+ result = return_here :name do c end
44
+
45
+ assert_equal 24, result
46
+ end
47
+
48
+ def test_return_here_nest
49
+ result = return_here do
50
+ return_here do
51
+ a
52
+ end
53
+ end
54
+
55
+ refute @after_a, 'return! did not skip after_a'
56
+
57
+ assert_equal 42, result
58
+ end
59
+
60
+ def test_return_here_no_return_bang
61
+ result = return_here do c end
62
+
63
+ assert_equal 24, result
64
+ end
65
+
66
+ def test_return_to_no_return_here
67
+ e = assert_raises NonLocalJumpError do
68
+ return_to :nonexistent
69
+ end
70
+
71
+ assert_equal 'return point :nonexistent was not set', e.message
72
+ end
73
+
74
+ def a() b; @after_a = true end
75
+ def b() return! 42 end
76
+
77
+ def c() 24 end
78
+
79
+ def d() return_here do e end; @after_e = true end
80
+ def e() return_to :name, 43 end
81
+
82
+ end
83
+
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: return_bang
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ version: "1.0"
10
+ platform: ruby
11
+ authors:
12
+ - Eric Hodel
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain:
16
+ - |
17
+ -----BEGIN CERTIFICATE-----
18
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy
19
+ YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu
20
+ ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk
21
+ cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ
22
+ FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76
23
+ LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J
24
+ U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm
25
+ Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY
26
+ mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd
27
+ g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh
28
+ sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
29
+ BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX
30
+ kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19
31
+ bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF
32
+ DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6
33
+ UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag
34
+ 14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v
35
+ x52qPcexcYZR7w==
36
+ -----END CERTIFICATE-----
37
+
38
+ date: 2011-12-21 00:00:00 Z
39
+ dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: minitest
42
+ prerelease: false
43
+ requirement: &id001 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ hash: 15
49
+ segments:
50
+ - 2
51
+ - 6
52
+ version: "2.6"
53
+ type: :development
54
+ version_requirements: *id001
55
+ - !ruby/object:Gem::Dependency
56
+ name: hoe
57
+ prerelease: false
58
+ requirement: &id002 !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ hash: 27
64
+ segments:
65
+ - 2
66
+ - 12
67
+ version: "2.12"
68
+ type: :development
69
+ version_requirements: *id002
70
+ description: |-
71
+ return_bang implements non-local exits from methods. Use return_bang to exit
72
+ back to a processing loop from deeply nested code, or just to confound your
73
+ enemies *and* your friends! What could possibly go wrong?
74
+ email:
75
+ - drbrain@segment7.net
76
+ executables: []
77
+
78
+ extensions: []
79
+
80
+ extra_rdoc_files:
81
+ - History.txt
82
+ - Manifest.txt
83
+ - README.rdoc
84
+ files:
85
+ - .autotest
86
+ - History.txt
87
+ - Manifest.txt
88
+ - README.rdoc
89
+ - Rakefile
90
+ - lib/return_bang.rb
91
+ - lib/return_bang/everywhere.rb
92
+ - test/test_return_bang.rb
93
+ - .gemtest
94
+ homepage: https://github.com/drbrain/return_bang
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options:
99
+ - --main
100
+ - README.rdoc
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ hash: 3
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project: return_bang
124
+ rubygems_version: 1.8.12
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: return_bang implements non-local exits from methods
128
+ test_files:
129
+ - test/test_return_bang.rb
metadata.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ `"t�TW��nW��G$��c�=gTV�=�z|��t"�;� ��Jv�_�X2��:����,����V��|c��xD��ܫ�s�]�}F�$�E�'uJ�{���۔Y���t������4KϞ2���E�j����u�ԕ�'�U� �A��y����$��ޅ
2
+ 稼�F�D�!�c����9 RsJ��҇�AF�a��y�=s`O�YQ�Z�w��~�~j�otɋ[1�臼�A��[�a_�`