asynchronize 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asynchronize.rb +7 -6
  3. data/readme.md +32 -30
  4. data/spec/spec.rb +15 -6
  5. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 912acc8b2e852aa7ccdd7fc09193f46fa64730f74972e9a955b8ba2bf3e40f1f
4
- data.tar.gz: c6b91b991495bb45ce6580596c9919a4a376437f3c441706c63f84a62941c77e
3
+ metadata.gz: d25d9fc46fcd88c468cb2441bf096e15773103f9ca2ad0d1930bdcc3f4e71b33
4
+ data.tar.gz: aab5b2f4c851c924dba5789282b7b575810ff1cf70bed84e5be0b167d8b1e2e5
5
5
  SHA512:
6
- metadata.gz: 86f7e988a2b97f36bb951045fca9214fd81b53239ae6a2fe5c0330a01f6f81c51bfcdb73052e2ac07bf434ec47dd362005274fa54243f8b3be9e4ec74fe53a96
7
- data.tar.gz: 274687d5e6b292d4f6bbf85515c95f9d4eb84bef5b8c9b5a51f6fd363ed99000ee7e36ff30672d6b714009077a637b3ecc43746a726631164b12d44d7ac1b563
6
+ metadata.gz: 54aed3b7e306361c981dfeb275ca0721ac3e02c9570fe34fdf02affab88c8fbbc1df6f771870bfe64eb9964731ef6842e09c11351236b37680bbb7c34fe119e2
7
+ data.tar.gz: ff384dc8ef4a33a885bdd05aaf33e065cbe5093964a05f549db37ddd8d16178dafd22f80f3edd9c41240eb7b634e74ff7cab2c1f46378430cba61d0bfb681214
@@ -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 named Asynchronized.
14
- # 2. Scopes that module to the calling class.
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
- # This always returns the same Proc object. In it's own method for clarity.
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 Class to prepend our module to
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 multithreaded methods.
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 the definitions. I prefer it at the top of classes.
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 'test'
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 manage the thread yourself; the returned value will be in the thread
32
- variable `:return_value` once it returns.
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
- puts thread.join[:return_value] # > test
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 to stay asynchronous when processing the result, you can pass it a block.
39
- It will still return the thread, and the return value will still be in the
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 do |return_value|
43
- puts return_value # > test
44
- end
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 `Thread#join` to
49
- ensure it completes before your process exits, and to catch any exceptions that
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 to
63
- memorize; sometimes you just want a normal thread. Now, just call asynchronize
64
- to make any method asynchronous.
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
- Beginning with version 1.0.0, this project will follow [Semantic Versioning]
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! It actually works just like inheritance, so it won't be a problem.
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 as of version 0.3.0. Actually,
94
- according to [cloc](https://www.npmjs.com/package/cloc) there's almost four
95
- times as many lines in the tests as the source. You should read it, I'd love
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. So I
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
 
@@ -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 :test
117
+ asynchronize :another_test
115
118
  end
116
119
  class ChildClassTest
117
- undef_method :test
118
- def test
120
+ def another_test
119
121
  return super.join[:return_value] + 1
120
122
  end
121
123
  end
122
- ChildClassTest.new.test.must_equal 6
124
+ ChildClassTest.new.another_test.must_equal 6
123
125
  end
124
126
  end
125
127
 
126
- describe "when asynchronize is called with no arguments" do
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.3.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: Sometimes you just want a regular thread without the overhead of a whole
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 multithreaded methods.
106
+ summary: A declarative syntax for creating asynchronous methods.
106
107
  test_files:
107
108
  - spec/spec.rb
108
109
  - spec/minitest_helper.rb