promise 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/README +35 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/lib/future.rb +50 -0
- data/lib/promise.rb +56 -0
- 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.
|
data/UNLICENSE
ADDED
@@ -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
|
data/lib/future.rb
ADDED
@@ -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
|
data/lib/promise.rb
ADDED
@@ -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
|
+
|