promise 0.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.
Files changed (7) hide show
  1. data/AUTHORS +1 -0
  2. data/README +35 -0
  3. data/UNLICENSE +24 -0
  4. data/VERSION +1 -0
  5. data/lib/future.rb +50 -0
  6. data/lib/promise.rb +56 -0
  7. metadata +79 -0
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ * Ben Lavender <blavender@gmail.com> (Lead developer)
data/README ADDED
@@ -0,0 +1,35 @@
1
+ # Promising Future
2
+ A glimpse of a promising future in which ruby supports delayed execution
3
+
4
+ ## Overview
5
+
6
+ require 'promise'
7
+ require 'future' # can just require future if using both
8
+
9
+ x = promise { 1 + 2 }
10
+ y = future { sleep 10; 5 + 5 }
11
+
12
+ puts x # => 3
13
+ # ... do work for 5 seconds
14
+ puts y # => 10, after blocking 5 seconds
15
+
16
+ Promises and futures both transparantly delay the execution of a block.
17
+ Futures run the evaluation of the block optimistically in another thread.
18
+
19
+ Note that this is pretty useless in irb, which will evaluate everything
20
+ as part of its read-eval-print loop.
21
+
22
+ ## Classes
23
+
24
+ * {Promise}
25
+ * {Future}
26
+
27
+ ## Source
28
+ The source is available at <http://github.com/bhuga/promising-future>
29
+
30
+ ## Author
31
+ Ben Lavender (http://github.com/bhuga)
32
+
33
+ ## Unlicense
34
+ Promising Future is free and unencumbered public domain software. For more
35
+ information, see <http://unlicense.org/> or the accompanying UNLICENSE file.
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,50 @@
1
+ require 'promise'
2
+
3
+ ##
4
+ # A delayed-execution result, optimistcally evaluated in a new Thread.
5
+ # @example
6
+ # x = future { sleep 5; 1 + 2 }
7
+ # # do stuff...
8
+ # y = x * 2 # => 6. blocks unless 5 seconds has passed.
9
+ #
10
+ class Future
11
+
12
+ instance_methods.each { |m| undef_method m unless m =~ /__/ }
13
+
14
+ ##
15
+ # @param [Proc] block
16
+ # @return [Future]
17
+ def initialize(block)
18
+ @promise = promise &block
19
+ @thread = Thread.new do
20
+ @promise.force
21
+ end
22
+ end
23
+
24
+ ##
25
+ # The value of the future's evaluation. Blocks until result available.
26
+ # @return [Any]
27
+ def force
28
+ @thread.join
29
+ @promise
30
+ end
31
+
32
+ # @private
33
+ def method_missing(method, *args, &block)
34
+ @promise.send(method, *args, &block)
35
+ end
36
+
37
+
38
+ end
39
+
40
+
41
+ module Kernel
42
+
43
+ # Create a new future
44
+ # @example
45
+ # x = future { 3 + 3 }
46
+ def future(&block)
47
+ Future.new(block)
48
+ end
49
+
50
+ end
@@ -0,0 +1,56 @@
1
+
2
+ ##
3
+ # A delayed-execution promise. Promises are only executed once.
4
+ # @example
5
+ # x = promise { factorial 20 }
6
+ # y = promise { fibonacci 10**6 }
7
+ # a = x + 1 # => factorial 20 + 1 after factorial calculates
8
+ # result = promise { a += y }
9
+ # abort "" # whew, we never needed to calculate y
10
+ # @example
11
+ # y = 5
12
+ # x = promise { y = y + 5 }
13
+ # x + 5 # => 15
14
+ # x + 5 # => 15
15
+ class Promise
16
+
17
+ instance_methods.each { |m| undef_method m unless m =~ /__/ }
18
+
19
+ # Returns a new promise
20
+ # @param [Proc] block
21
+ # @return [Promise]
22
+ def initialize(block)
23
+ if block.arity > 0
24
+ raise ArgumentError, "Cannot store a promise that requires an argument"
25
+ end
26
+ @block = block
27
+ @mutex = Mutex.new
28
+ end
29
+
30
+ # Force the evaluation of this promise immediately
31
+ # @return [Any]
32
+ def force
33
+ @mutex.synchronize do
34
+ unless @result
35
+ @result = @block.call
36
+ end
37
+ end
38
+ @result
39
+ end
40
+
41
+ def method_missing(method, *args, &block)
42
+ force unless @result
43
+ @result.send(method, *args, &block)
44
+ end
45
+ end
46
+
47
+ module Kernel
48
+
49
+ # Create a new promise
50
+ # @example
51
+ # x = promise { 3 + 3 }
52
+ def promise(&block)
53
+ Promise.new(block)
54
+ end
55
+
56
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: promise
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Lavender
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-11 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.2
34
+ version:
35
+ description: " A glimpse into a promising future, in which ruby supports delayed execution.\n Provides 'promise' and 'future' functions.\n"
36
+ email: blavender@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - AUTHORS
45
+ - README
46
+ - UNLICENSE
47
+ - VERSION
48
+ - lib/future.rb
49
+ - lib/promise.rb
50
+ has_rdoc: false
51
+ homepage: http://promise.rubyforge.org/
52
+ licenses:
53
+ - Public Domain
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.8.2
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project: promising-future
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: Promises and futures for Ruby
78
+ test_files: []
79
+