promise 0.3.0 → 0.3.1

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 +7 -0
  2. data/VERSION +1 -1
  3. data/lib/future.rb +14 -18
  4. data/lib/promise.rb +25 -18
  5. metadata +43 -59
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6ae5a36893d54edf8775e75177c2f8c7e269c2d7
4
+ data.tar.gz: 995b75b7423afc3ffa444067569eb6a1b688947b
5
+ SHA512:
6
+ metadata.gz: 2daaaff146b272eb18a9c87eb5bddb190c77ffeff5345bec3f6755aee71fdcec73c0b6df0d20c6ced5440cc0d788e7ce51f877e1b13cadf6d94db15838dedc24
7
+ data.tar.gz: 3891a5a381c112659a52baaa0da4bda7f42c4873e27bf8564d7cf789c1a7d4ccb1f9ef7b3c22a178f3da467e1fd051989ab45d0a2949e9ddab9655e0f93d9d08
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
@@ -8,7 +8,8 @@ require 'promise'
8
8
  # # do stuff...
9
9
  # y = x * 2 # => 6. blocks unless 5 seconds has passed.
10
10
  #
11
- class Future < Promise
11
+ class Future < defined?(BasicObject) ? BasicObject : Object
12
+ instance_methods.each { |m| undef_method m unless m =~ /^(__.*|object_id)$/ }
12
13
 
13
14
  ##
14
15
  # Creates a new future.
@@ -16,14 +17,8 @@ class Future < Promise
16
17
  # @yield [] The block to evaluate optimistically.
17
18
  # @see Kernel#future
18
19
  def initialize(&block)
19
- super
20
- # Ruby won't assign the value of @thread until after the thread is off and
21
- # running, meaning we can run into an unset @thread when joining off in
22
- # __force__, instead of it being Thread.current. We could leave it as nil
23
- # and check for that, but this is a more explicit way to watch for this
24
- # easy-to-miss gotcha.
25
- @thread = NOT_SET
26
- @thread = ::Thread.new { __force__ }
20
+ @promise = ::Promise.new(&block)
21
+ @thread = ::Thread.new { @promise.__force__ }
27
22
  end
28
23
 
29
24
  ##
@@ -31,24 +26,25 @@ class Future < Promise
31
26
  #
32
27
  # @return [Object]
33
28
  def __force__
34
- @thread.join unless (@thread == ::Thread.current) || @thread.equal?(NOT_SET)
35
- super
29
+ @thread.join if @thread
30
+ @promise
36
31
  end
37
32
  alias_method :force, :__force__
38
33
 
39
-
40
34
  ##
41
- # Returns true if klass.equal?(Future), if klass.equal?(Promise), or the
42
- # underlying block returns an instance of the given klass
35
+ # Does this future support the given method?
43
36
  #
44
- # @param [Class]
45
- # @return [true, false]
46
- def is_a?(klass)
47
- klass.equal?(::Future) || super
37
+ # @param [Symbol]
38
+ # @return [Boolean]
39
+ def respond_to?(method, include_all=false)
40
+ :force.equal?(method) || :__force__.equal?(method) || __force__.respond_to?(method, include_all)
48
41
  end
49
42
 
50
43
  private
51
44
 
45
+ def method_missing(method, *args, &block)
46
+ __force__.__send__(method, *args, &block)
47
+ end
52
48
  end
53
49
 
54
50
  module Kernel
@@ -17,7 +17,7 @@
17
17
  class Promise < defined?(BasicObject) ? BasicObject : ::Object
18
18
  NOT_SET = ::Object.new.freeze
19
19
 
20
- instance_methods.each { |m| undef_method m unless m.to_s =~ /__/ }
20
+ instance_methods.each { |m| undef_method m unless m =~ /^(__.*|object_id)$/ }
21
21
 
22
22
  ##
23
23
  # Creates a new promise.
@@ -29,7 +29,7 @@ class Promise < defined?(BasicObject) ? BasicObject : ::Object
29
29
  # @see Kernel#promise
30
30
  def initialize(&block)
31
31
  if block.arity > 0
32
- raise ArgumentError, "Cannot store a promise that requires an argument"
32
+ ::Kernel.raise ::ArgumentError, "Cannot store a promise that requires an argument"
33
33
  end
34
34
  @block = block
35
35
  @mutex = ::Mutex.new
@@ -43,14 +43,14 @@ class Promise < defined?(BasicObject) ? BasicObject : ::Object
43
43
  # @return [Object]
44
44
  def __force__
45
45
  @mutex.synchronize do
46
- if !__forced?
46
+ if @result.equal?(NOT_SET) && @error.equal?(NOT_SET)
47
47
  begin
48
48
  @result = @block.call
49
49
  rescue ::Exception => e
50
50
  @error = e
51
51
  end
52
52
  end
53
- end unless __forced?
53
+ end if @result.equal?(NOT_SET) && @error.equal?(NOT_SET)
54
54
  # BasicObject won't send raise to Kernel
55
55
  @error.equal?(NOT_SET) ? @result : ::Kernel.raise(@error)
56
56
  end
@@ -59,28 +59,35 @@ class Promise < defined?(BasicObject) ? BasicObject : ::Object
59
59
  ##
60
60
  # Does this promise support the given method?
61
61
  #
62
- # @param [Symbol]
63
- # @return [true, false]
64
- def respond_to?(method)
65
- :__forced?.equal?(method) || :force.equal?(method) || :__force__.equal?(method) || __force__.respond_to?(method)
62
+ # @param [Symbol, Boolean]
63
+ # @return [Boolean]
64
+ def respond_to?(method, include_all=false)
65
+ # If the promised object implements marshal_dump, Marshal will use it in
66
+ # preference to our _dump, so make sure that doesn't happen.
67
+ return false if :marshal_dump.equal?(method)
68
+
69
+ :_dump.equal?(method) || # for Marshal
70
+ :force.equal?(method) ||
71
+ :__force__.equal?(method) ||
72
+ __force__.respond_to?(method, include_all)
66
73
  end
67
74
 
68
75
  ##
69
- # Returns true if klass.equal?(Promise) or the underlying block returns an
70
- # instance of the given klass
76
+ # Method used by Marshal to serialize the object. Forces evaluation.
71
77
  #
72
- # @param [Class]
73
- # @return [true, false]
74
- def is_a?(klass)
75
- klass.equal?(::Promise) || __force__.is_a?(klass)
78
+ # @param [Integer] limit -- refer to Marshal doc
79
+ # @return [Object]
80
+ def _dump(limit)
81
+ ::Marshal.dump(__force__, limit)
76
82
  end
77
83
 
78
84
  ##
79
- # Returns true if this promise has finished executing
85
+ # Method used by Marshal to deserialize the object.
80
86
  #
81
- # @return [true, false]
82
- def __forced?
83
- !(@result.equal?(NOT_SET) && @error.equal?(NOT_SET))
87
+ # @param [Object]
88
+ # @return [Promise]
89
+ def self._load(obj)
90
+ ::Marshal.load(obj)
84
91
  end
85
92
 
86
93
  private
metadata CHANGED
@@ -1,96 +1,80 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: promise
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 3
8
- - 0
9
- version: 0.3.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - Ben Lavender
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2010-07-05 00:00:00 -05:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
11
+ date: 2014-12-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: rspec
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
25
17
  - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 1
29
- - 3
30
- - 0
18
+ - !ruby/object:Gem::Version
31
19
  version: 1.3.0
32
20
  type: :development
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: yard
36
21
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
39
31
  - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- - 5
44
- - 8
32
+ - !ruby/object:Gem::Version
45
33
  version: 0.5.8
46
34
  type: :development
47
- version_requirements: *id002
48
- description: " A glimpse of a promising future in which Ruby supports delayed execution.\n Provides global 'promise' and 'future' methods.\n"
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.8
41
+ description: |2
42
+ A glimpse of a promising future in which Ruby supports delayed execution.
43
+ Provides global 'promise' and 'future' methods.
49
44
  email: blavender@gmail.com
50
45
  executables: []
51
-
52
46
  extensions: []
53
-
54
47
  extra_rdoc_files: []
55
-
56
- files:
48
+ files:
57
49
  - AUTHORS
58
50
  - README
59
51
  - UNLICENSE
60
52
  - VERSION
61
53
  - lib/future.rb
62
54
  - lib/promise.rb
63
- has_rdoc: false
64
55
  homepage: http://promise.rubyforge.org/
65
- licenses:
56
+ licenses:
66
57
  - Public Domain
58
+ metadata: {}
67
59
  post_install_message:
68
60
  rdoc_options: []
69
-
70
- require_paths:
61
+ require_paths:
71
62
  - lib
72
- required_ruby_version: !ruby/object:Gem::Requirement
73
- requirements:
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
74
65
  - - ">="
75
- - !ruby/object:Gem::Version
76
- segments:
77
- - 1
78
- - 8
79
- - 2
66
+ - !ruby/object:Gem::Version
80
67
  version: 1.8.2
81
- required_rubygems_version: !ruby/object:Gem::Requirement
82
- requirements:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
83
70
  - - ">="
84
- - !ruby/object:Gem::Version
85
- segments:
86
- - 0
87
- version: "0"
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
88
73
  requirements: []
89
-
90
74
  rubyforge_project: promising-future
91
- rubygems_version: 1.3.6
75
+ rubygems_version: 2.2.2
92
76
  signing_key:
93
- specification_version: 3
77
+ specification_version: 4
94
78
  summary: Promises and futures for Ruby
95
79
  test_files: []
96
-
80
+ has_rdoc: false