asynchronize 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Maintainability](https://api.codeclimate.com/v1/badges/30d40e270a3d7a0775a9/maintainability)](https://codeclimate.com/github/kennycoc/asynchronize/maintainability)
|
3
3
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/30d40e270a3d7a0775a9/test_coverage)](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
|