asynchronize 0.3.0 → 0.4.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/lib/asynchronize.rb +7 -6
- data/readme.md +32 -30
- data/spec/spec.rb +15 -6
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d25d9fc46fcd88c468cb2441bf096e15773103f9ca2ad0d1930bdcc3f4e71b33
|
4
|
+
data.tar.gz: aab5b2f4c851c924dba5789282b7b575810ff1cf70bed84e5be0b167d8b1e2e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54aed3b7e306361c981dfeb275ca0721ac3e02c9570fe34fdf02affab88c8fbbc1df6f771870bfe64eb9964731ef6842e09c11351236b37680bbb7c34fe119e2
|
7
|
+
data.tar.gz: ff384dc8ef4a33a885bdd05aaf33e065cbe5093964a05f549db37ddd8d16178dafd22f80f3edd9c41240eb7b634e74ff7cab2c1f46378430cba61d0bfb681214
|
data/lib/asynchronize.rb
CHANGED
@@ -4,15 +4,15 @@
|
|
4
4
|
# Defines only one method on the including class: `asynchronize`
|
5
5
|
#
|
6
6
|
module Asynchronize
|
7
|
+
# Defines the asynchronize method
|
7
8
|
def self.included(base)
|
8
9
|
base.class_eval do
|
9
10
|
##
|
10
11
|
# Call to asynchronize a method.
|
11
12
|
#
|
12
13
|
# This does two things
|
13
|
-
# 1. Creates and prepends a module
|
14
|
-
# 2.
|
15
|
-
# 3. Defines each of the passed methods on that module.
|
14
|
+
# 1. Creates and prepends a module <BaseName>::Asynchronized.
|
15
|
+
# 2. Defines each of the passed methods on that module.
|
16
16
|
#
|
17
17
|
# Additional notes:
|
18
18
|
# - The new methods wrap the old method within Thread.new.
|
@@ -53,7 +53,7 @@ module Asynchronize
|
|
53
53
|
##
|
54
54
|
# Build Method
|
55
55
|
#
|
56
|
-
#
|
56
|
+
# This always returns the same Proc object. In it's own method for clarity.
|
57
57
|
#
|
58
58
|
# @return [Proc] The actual asynchronous method defined.
|
59
59
|
#
|
@@ -61,7 +61,8 @@ module Asynchronize
|
|
61
61
|
return Proc.new do |*args, &block|
|
62
62
|
return Thread.new(args, block) do |thread_args, thread_block|
|
63
63
|
Thread.current[:return_value] = super(*thread_args)
|
64
|
-
thread_block.call(Thread.current[:return_value]) if thread_block
|
64
|
+
next thread_block.call(Thread.current[:return_value]) if thread_block
|
65
|
+
Thread.current[:return_value]
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
@@ -74,7 +75,7 @@ module Asynchronize
|
|
74
75
|
# - If the container module is defined, return it.
|
75
76
|
# - If the container module is not defined, create, prepend, and return it.
|
76
77
|
#
|
77
|
-
# @param obj [Class] The
|
78
|
+
# @param obj [Class] The class the module should belong to.
|
78
79
|
# @return [Module] The already prepended module to define our methods on.
|
79
80
|
#
|
80
81
|
def self._get_container_for(obj)
|
data/readme.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
[](https://codeclimate.com/github/kennycoc/asynchronize/maintainability)
|
3
3
|
[](https://codeclimate.com/github/kennycoc/asynchronize/test_coverage)
|
4
4
|
# Asynchronize
|
5
|
-
### A declarative syntax for creating
|
5
|
+
### A declarative syntax for creating asynchronous methods.
|
6
6
|
|
7
7
|
Find yourself writing the same boilerplate for all your asynchronous methods?
|
8
8
|
Get dry with asynchronize.
|
@@ -16,10 +16,10 @@ Create a class with asynchronized methods
|
|
16
16
|
require 'asynchronize'
|
17
17
|
class Test
|
18
18
|
include Asynchronize
|
19
|
-
# Can be called before or after
|
19
|
+
# Can be called before or after method definitions. I prefer it at the top of classes.
|
20
20
|
asynchronize :my_test, :my_other_test
|
21
21
|
def my_test
|
22
|
-
return '
|
22
|
+
return 'testing'
|
23
23
|
end
|
24
24
|
def my_other_test
|
25
25
|
#do stuff here too
|
@@ -28,26 +28,29 @@ end
|
|
28
28
|
```
|
29
29
|
|
30
30
|
Now, to call those methods.
|
31
|
-
You can
|
32
|
-
|
31
|
+
You can pass a block, and access the return value as the block parameter. The
|
32
|
+
return value from your block will be accessible at `Thread#value` and the return
|
33
|
+
value from the original function will be accessible via the thread variable
|
34
|
+
`:return_value`.
|
33
35
|
```Ruby
|
34
|
-
thread = Test.new.my_test
|
35
|
-
|
36
|
+
thread = Test.new.my_test do |return_value|
|
37
|
+
return return_value.length
|
38
|
+
end
|
39
|
+
thread.value # > 7
|
40
|
+
thread[:return_value] # > testing
|
36
41
|
```
|
37
42
|
|
38
|
-
Or
|
39
|
-
|
40
|
-
thread variable `:return_value`
|
43
|
+
Or, without a block `Thread#value` and `thread[:return_value]` both reference
|
44
|
+
the return value of the original function.
|
41
45
|
```Ruby
|
42
|
-
thread = Test.new.my_test
|
43
|
-
|
44
|
-
|
45
|
-
thread.join[:return_value] # > also test
|
46
|
+
thread = Test.new.my_test
|
47
|
+
puts thread.value # > testing
|
48
|
+
puts thread[:return_value] # > testing
|
46
49
|
```
|
47
50
|
|
48
|
-
As you can see, it's just a regular thread. Make sure you call
|
49
|
-
ensure it completes before your process exits,
|
50
|
-
may have been thrown!
|
51
|
+
As you can see, it's just a regular thread. Make sure you call either
|
52
|
+
`Thread#value` or`Thread#join` to ensure it completes before your process exits,
|
53
|
+
and to catch any exceptions that may have been thrown!
|
51
54
|
|
52
55
|
## Inspiration
|
53
56
|
While working on another project, I found myself writing this way too often:
|
@@ -59,23 +62,23 @@ def method_name(args)
|
|
59
62
|
end
|
60
63
|
```
|
61
64
|
It's extra typing, and adds an unneeded extra layer of nesting. I couldn't find
|
62
|
-
an existing library that wasn't trying add new layers of abstraction
|
63
|
-
|
64
|
-
|
65
|
+
an existing library that wasn't trying add new layers of abstraction I didn't
|
66
|
+
need; sometimes you just want a normal thread. Now, just call asynchronize to
|
67
|
+
make any method asynchronous.
|
65
68
|
|
66
69
|
## Versioning Policy
|
67
|
-
|
68
|
-
|
69
|
-
(https://semver.org) until then, the patch number (0.0.x) will be
|
70
|
+
Beginning with version 1.0.0, this project will follow [Semantic
|
71
|
+
Versioning](https://semver.org). Until then, the patch number (0.0.x) will be
|
70
72
|
updated for any changes that do not affect the public interface. Versions that
|
71
|
-
increment the minor number will have at least one of the following. A new
|
73
|
+
increment the minor number (0.x.0) will have at least one of the following. A new
|
72
74
|
feature will be added, some feature will be deprecated, or some previously
|
73
75
|
deprecated feature will be removed. Deprecated features will be removed on the
|
74
76
|
very next version that increments the minor version number.
|
75
77
|
|
76
78
|
## FAQ
|
77
79
|
### Doesn't metaprogramming hurt performance?
|
78
|
-
Not at all!
|
80
|
+
Not at all! What we're doing in this project actually works exactly like
|
81
|
+
inheritance, so it won't be a problem.
|
79
82
|
|
80
83
|
### So, how does it work?
|
81
84
|
When you `include Asynchronize` it creates an `asynchronize` method on your
|
@@ -90,10 +93,9 @@ method's return values, I thought it was important to allow this.
|
|
90
93
|
|
91
94
|
### Why do I need another gem? My code's bloated enough as it is?
|
92
95
|
It's super tiny. Just a light wrapper around the existing language features.
|
93
|
-
Seriously, it's just around forty lines of code
|
94
|
-
|
95
|
-
|
96
|
-
feedback!
|
96
|
+
Seriously, it's just around forty lines of code. Actually, according to
|
97
|
+
[cloc](https://www.npmjs.com/package/cloc) there's almost four times as many
|
98
|
+
lines in the tests as the source. You should read it, I'd love feedback!
|
97
99
|
|
98
100
|
### Do you accept contributions?
|
99
101
|
Absolutely!
|
@@ -118,7 +120,7 @@ preventing usage of `super` with `define_method`. I'm unable to find a suitable
|
|
118
120
|
workaround for this issue. (`method(__method__).super_method.call` causes
|
119
121
|
problems when a method inherits from the asynchronized class.)
|
120
122
|
|
121
|
-
Luckily, all major Ruby implementations support Ruby language version 2.3
|
123
|
+
Luckily, all major Ruby implementations support Ruby language version 2.3, so I
|
122
124
|
don't see this as a huge problem. If anyone wants support for older versions,
|
123
125
|
and knows how to workaround this issue, feel free to submit a pull request.
|
124
126
|
|
data/spec/spec.rb
CHANGED
@@ -9,6 +9,9 @@ class BasicSpec < Minitest::Test
|
|
9
9
|
def test(val=5)
|
10
10
|
return val
|
11
11
|
end
|
12
|
+
def another_test(val=5)
|
13
|
+
return val
|
14
|
+
end
|
12
15
|
end
|
13
16
|
end
|
14
17
|
after do
|
@@ -111,25 +114,31 @@ class BasicSpec < Minitest::Test
|
|
111
114
|
end
|
112
115
|
it "should be able to call super when super has been asynchronized" do
|
113
116
|
class Test
|
114
|
-
asynchronize :
|
117
|
+
asynchronize :another_test
|
115
118
|
end
|
116
119
|
class ChildClassTest
|
117
|
-
|
118
|
-
def test
|
120
|
+
def another_test
|
119
121
|
return super.join[:return_value] + 1
|
120
122
|
end
|
121
123
|
end
|
122
|
-
ChildClassTest.new.
|
124
|
+
ChildClassTest.new.another_test.must_equal 6
|
123
125
|
end
|
124
126
|
end
|
125
127
|
|
126
|
-
describe "when asynchronize is called
|
127
|
-
it "should not define an Asynchronized container" do
|
128
|
+
describe "when asynchronize is called" do
|
129
|
+
it "should not define an Asynchronized container if there are no arguments" do
|
128
130
|
Test.asynchronize
|
129
131
|
Test.ancestors.find do |a|
|
130
132
|
a.name.split('::').include? 'Asynchronized'
|
131
133
|
end.must_be_nil
|
132
134
|
end
|
135
|
+
it "should not define two modules if we call it twice" do
|
136
|
+
Test.asynchronize :test
|
137
|
+
Test.asynchronize :another_test
|
138
|
+
Test.ancestors.select do |a|
|
139
|
+
a.name.split('::').include? 'Asynchronized'
|
140
|
+
end.length.must_equal 1
|
141
|
+
end
|
133
142
|
end
|
134
143
|
end
|
135
144
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asynchronize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenneth Cochran
|
@@ -66,7 +66,8 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0.11'
|
69
|
-
description:
|
69
|
+
description: Asynchronize provides a declarative syntax for creating asynchronous
|
70
|
+
methods. Sometimes you just want a regular thread without the overhead of a whole
|
70
71
|
new layer of abstraction. Asynchronize provides a declarative syntax to wrap any
|
71
72
|
method in a Thread.
|
72
73
|
email: kenneth.cochran101@gmail.com
|
@@ -102,7 +103,7 @@ rubyforge_project:
|
|
102
103
|
rubygems_version: 2.7.6
|
103
104
|
signing_key:
|
104
105
|
specification_version: 4
|
105
|
-
summary: A declarative syntax for creating
|
106
|
+
summary: A declarative syntax for creating asynchronous methods.
|
106
107
|
test_files:
|
107
108
|
- spec/spec.rb
|
108
109
|
- spec/minitest_helper.rb
|