mercury_amqp 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 95133530de1763cec95808562a5e7fc63051357c
4
- data.tar.gz: 0c67f736b817ae297846b28daee0ecaba4b5db44
3
+ metadata.gz: 4870a8839ae27cd315c1812fabf3657b83719894
4
+ data.tar.gz: 8f88e142bdd7353de606efb5e64952b947b8061d
5
5
  SHA512:
6
- metadata.gz: 6d41a7d999b7f16ba2a19cd5a1bf625bf0899cffadfa08ae0d4a7d0db636ee37786ab752747a2e0e59a5a609d22be36bbf2ef1921aaa01edcb0c58a20ae49427
7
- data.tar.gz: 31cee609bd834fc298f7879fb8ef26d65f3cd6cbe5219825c409a638049a9747fbacd9f01711d2d603d96182e611ab7f0280869d31d805bb3526b1e08d7b810a
6
+ metadata.gz: ca6fc752c0a82c9f35d61fafa80ceed4b1cb18577c06ca8ab49377cd471ad6c8e1b14a75962e66d54bf064b65eb0786cda19bae1a8474004e4796713932916f0
7
+ data.tar.gz: 322754fee9b93640f7d32f046af978f88373484b478c5a38d71a10cdc1a48b92b58e50fd0adcbef6330b6f5163d9e6c64d7606a24c1fb21becc0a35573b4d906
@@ -1,23 +1,25 @@
1
- class Cps
2
- module Methods
3
- def lift(&block)
4
- Cps.lift(&block)
5
- end
1
+ class Mercury
2
+ class Cps
3
+ module Methods
4
+ def lift(&block)
5
+ Cps.lift(&block)
6
+ end
6
7
 
7
- def seq(&block)
8
- Cps.seq(&block)
9
- end
8
+ def seq(&block)
9
+ Cps.seq(&block)
10
+ end
10
11
 
11
- def seql(&block)
12
- Cps.seql(2, &block)
13
- end
12
+ def seql(&block)
13
+ Cps.seql(2, &block)
14
+ end
14
15
 
15
- def seqp(&block)
16
- Cps.seqp(&block)
17
- end
16
+ def seqp(&block)
17
+ Cps.seqp(&block)
18
+ end
18
19
 
19
- def cps(&block)
20
- Cps.new(&block)
20
+ def cps(&block)
21
+ Cps.new(&block)
22
+ end
21
23
  end
22
24
  end
23
25
  end
@@ -1,19 +1,21 @@
1
- class Cps
1
+ class Mercury
2
+ class Cps
2
3
 
3
- # Syntactic sugar for and_then chains.
4
- def self.seq(&block)
5
- s = Seq.new
6
- block.call(s.method(:chain))
7
- s.m
8
- end
9
-
10
- class Seq
11
- def m
12
- @m ||= Cps.identity # we need an initial Cps to chain onto
4
+ # Syntactic sugar for and_then chains.
5
+ def self.seq(&block)
6
+ s = Seq.new
7
+ block.call(s.method(:chain))
8
+ s.m
13
9
  end
14
10
 
15
- def chain(proc=nil, &block)
16
- @m = m.and_then(&(proc || block))
11
+ class Seq
12
+ def m
13
+ @m ||= Cps.identity # we need an initial Cps to chain onto
14
+ end
15
+
16
+ def chain(proc=nil, &block)
17
+ @m = m.and_then(&(proc || block))
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -1,67 +1,69 @@
1
1
  require 'binding_of_caller'
2
2
 
3
- class Cps
4
- # Syntactic sugar for and_then chains.
5
- def self.seql(depth=1, &block)
6
- # EXPERIMENTAL
7
- # The trick here is to execute the block in a context where
8
- # 1. we can simulate local let-bound variables, and
9
- # 2. the block can access variables and methods available
10
- # outside the call to seql.
11
- #
12
- # To achieve this, we instance_exec the block in a SeqWithLet
13
- # object, which provides the let bound variables (as methods)
14
- # and uses method_missing to proxy other methods to the parent
15
- # binding.
16
- #
17
- # Note: parent instance variables are not available inside the block.
18
- # Note: keyword arguments are not proxied to methods called in the parent binding
19
- context = SeqWithLet.new(binding.of_caller(depth))
20
- context.instance_exec(&block)
21
- context.__chain
22
- end
3
+ class Mercury
4
+ class Cps
5
+ # Syntactic sugar for and_then chains.
6
+ def self.seql(depth=1, &block)
7
+ # EXPERIMENTAL
8
+ # The trick here is to execute the block in a context where
9
+ # 1. we can simulate local let-bound variables, and
10
+ # 2. the block can access variables and methods available
11
+ # outside the call to seql.
12
+ #
13
+ # To achieve this, we instance_exec the block in a SeqWithLet
14
+ # object, which provides the let bound variables (as methods)
15
+ # and uses method_missing to proxy other methods to the parent
16
+ # binding.
17
+ #
18
+ # Note: parent instance variables are not available inside the block.
19
+ # Note: keyword arguments are not proxied to methods called in the parent binding
20
+ context = SeqWithLet.new(binding.of_caller(depth))
21
+ context.instance_exec(&block)
22
+ context.__chain
23
+ end
23
24
 
24
- class SeqWithLet
25
+ class SeqWithLet
25
26
 
26
- def and_then(&block)
27
- @__chain = __chain.and_then(&block)
28
- end
27
+ def and_then(&block)
28
+ @__chain = __chain.and_then(&block)
29
+ end
29
30
 
30
- def and_lift(&block)
31
- @__chain = __chain.and_lift(&block)
32
- end
31
+ def and_lift(&block)
32
+ @__chain = __chain.and_lift(&block)
33
+ end
33
34
 
34
- def let(name, &block)
35
- and_then(&block)
36
- and_then do |value|
37
- __values[name] = value
38
- Cps.lift{value}
35
+ def let(name, &block)
36
+ and_then(&block)
37
+ and_then do |value|
38
+ __values[name] = value
39
+ Cps.lift{value}
40
+ end
39
41
  end
40
- end
41
42
 
42
- def initialize(parent_binding)
43
- @__parent_binding = parent_binding
44
- end
43
+ def initialize(parent_binding)
44
+ @__parent_binding = parent_binding
45
+ end
45
46
 
46
- def __chain
47
- @__chain ||= Cps.identity
48
- end
47
+ def __chain
48
+ @__chain ||= Cps.identity
49
+ end
49
50
 
50
- def method_missing(name, *args, &block)
51
- __values.fetch(name) { __parent_call(name.to_s, *args, &block) }
52
- end
51
+ def method_missing(name, *args, &block)
52
+ __values.fetch(name) { __parent_call(name.to_s, *args, &block) }
53
+ end
53
54
 
54
- def __parent_call(name, *args, &block)
55
- @__parent_caller ||= @__parent_binding.eval <<-EOD
55
+ def __parent_call(name, *args, &block)
56
+ @__parent_caller ||= @__parent_binding.eval <<-EOD
56
57
  proc do |name, *args, &block|
57
58
  send(name, *args, &block)
58
59
  end
59
- EOD
60
- @__parent_caller.call(name, *args, &block)
61
- end
60
+ EOD
61
+ @__parent_caller.call(name, *args, &block)
62
+ end
62
63
 
63
- def __values
64
- @__values ||= {}
64
+ def __values
65
+ @__values ||= {}
66
+ end
65
67
  end
66
68
  end
67
69
  end
data/lib/mercury/cps.rb CHANGED
@@ -13,85 +13,87 @@ require 'mercury/utils'
13
13
  # passing. It basically wraps a CPS proc with methods for
14
14
  # composing them.
15
15
  # See http://codon.com/refactoring-ruby-with-monads
16
- class Cps
17
- attr_reader :cps
16
+ class Mercury
17
+ class Cps
18
+ attr_reader :cps
18
19
 
19
- # @param [Proc] cps a CPS proc (signature: *args, &k)
20
- def initialize(&cps)
21
- @cps = cps
22
- end
20
+ # @param [Proc] cps a CPS proc (signature: *args, &k)
21
+ def initialize(&cps)
22
+ @cps = cps
23
+ end
23
24
 
24
- # Applies the wrapped proc. If the CPS return value
25
- # is not needed, the continuation k may be omitted.
26
- # Returns the return value of the continuation.
27
- def run(*args, &k)
28
- k ||= proc { |x| x }
29
- cps.call(*args, &k)
30
- end
25
+ # Applies the wrapped proc. If the CPS return value
26
+ # is not needed, the continuation k may be omitted.
27
+ # Returns the return value of the continuation.
28
+ def run(*args, &k)
29
+ k ||= proc { |x| x }
30
+ cps.call(*args, &k)
31
+ end
31
32
 
32
- # The "bind" operation; composes two Cps
33
- # @param [Proc] pm a proc that takes the output of this
34
- # Cps and returns a Cps
35
- def and_then(&pm)
36
- Cps.new do |*args, &k|
37
- self.run(*args) do |*args2|
38
- next_cps = pm.call(*args2)
39
- next_cps.is_a?(Cps) or raise "'and_then' block did not return a Cps. Did you want 'and_lift'? at #{pm.source_location}"
40
- next_cps.run(&k)
33
+ # The "bind" operation; composes two Cps
34
+ # @param [Proc] pm a proc that takes the output of this
35
+ # Cps and returns a Cps
36
+ def and_then(&pm)
37
+ Cps.new do |*args, &k|
38
+ self.run(*args) do |*args2|
39
+ next_cps = pm.call(*args2)
40
+ next_cps.is_a?(Cps) or raise "'and_then' block did not return a Cps. Did you want 'and_lift'? at #{pm.source_location}"
41
+ next_cps.run(&k)
42
+ end
41
43
  end
42
44
  end
43
- end
44
45
 
45
- # equivalent to: and_then { lift { ... } }
46
- def and_lift(&p)
47
- and_then do |*args|
48
- Cps.lift { p.call(*args) }
46
+ # equivalent to: and_then { lift { ... } }
47
+ def and_lift(&p)
48
+ and_then do |*args|
49
+ Cps.lift { p.call(*args) }
50
+ end
49
51
  end
50
- end
51
52
 
52
- # Returns a Cps for a non-CPS proc.
53
- def self.lift(&p)
54
- new { |*args, &k| k.call(p.call(*args)) }
55
- end
53
+ # Returns a Cps for a non-CPS proc.
54
+ def self.lift(&p)
55
+ new { |*args, &k| k.call(p.call(*args)) }
56
+ end
56
57
 
57
- # The identity function as a Cps.
58
- def self.identity
59
- new { |*args, &k| k.call(*args) }
60
- end
58
+ # The identity function as a Cps.
59
+ def self.identity
60
+ new { |*args, &k| k.call(*args) }
61
+ end
61
62
 
62
- # Returns a Cps that executes the provided Cpses concurrently.
63
- # Once all complete, their return values are passed to the continuation
64
- # in an array with positions corresponding to the provided Cpses.
65
- def self.concurrently(*cpss)
66
- cpss = Utils.unsplat(cpss)
63
+ # Returns a Cps that executes the provided Cpses concurrently.
64
+ # Once all complete, their return values are passed to the continuation
65
+ # in an array with positions corresponding to the provided Cpses.
66
+ def self.concurrently(*cpss)
67
+ cpss = Utils.unsplat(cpss)
67
68
 
68
- Cps.new do |*in_args, &k|
69
- pending_completions = cpss
70
- returned_args = []
71
- cpss.each_with_index do |cps, i|
72
- cps.run(*in_args) do |*out_args|
73
- returned_args[i] = out_args
74
- pending_completions.delete(cps)
75
- if pending_completions.none?
76
- k.call(returned_args)
69
+ Cps.new do |*in_args, &k|
70
+ pending_completions = cpss
71
+ returned_args = []
72
+ cpss.each_with_index do |cps, i|
73
+ cps.run(*in_args) do |*out_args|
74
+ returned_args[i] = out_args
75
+ pending_completions.delete(cps)
76
+ if pending_completions.none?
77
+ k.call(returned_args)
78
+ end
77
79
  end
78
80
  end
79
81
  end
80
82
  end
81
- end
82
83
 
83
- # Calls and_then for each x.
84
- # @yieldparam x [Object] An item from xs
85
- # @yieldparam *args [Objects] The value(s) passed from the last action
86
- # @yieldreturn [Cps] The next action to add to the chain
87
- def inject(xs, &block)
88
- xs.inject(self) do |chain, x|
89
- chain.and_then { |*args| block.call(x, *args) }
84
+ # Calls and_then for each x.
85
+ # @yieldparam x [Object] An item from xs
86
+ # @yieldparam *args [Objects] The value(s) passed from the last action
87
+ # @yieldreturn [Cps] The next action to add to the chain
88
+ def inject(xs, &block)
89
+ xs.inject(self) do |chain, x|
90
+ chain.and_then { |*args| block.call(x, *args) }
91
+ end
90
92
  end
91
- end
92
93
 
93
- # equivalent to Cps.identity.inject(...)
94
- def self.inject(xs, &block)
95
- Cps.identity.inject(xs, &block)
94
+ # equivalent to Cps.identity.inject(...)
95
+ def self.inject(xs, &block)
96
+ Cps.identity.inject(xs, &block)
97
+ end
96
98
  end
97
99
  end
data/lib/mercury/utils.rb CHANGED
@@ -1,9 +1,11 @@
1
- class Utils
2
- def self.unsplat(args)
3
- if args.size == 1 and args.first.is_a?(Array)
4
- args.first
5
- else
6
- args
1
+ class Mercury
2
+ class Utils
3
+ def self.unsplat(args)
4
+ if args.size == 1 and args.first.is_a?(Array)
5
+ args.first
6
+ else
7
+ args
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,3 +1,3 @@
1
1
  class Mercury
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
  require 'mercury/cps'
3
3
 
4
+ Cps = Mercury::Cps
5
+
4
6
  describe Cps do
5
7
  include Cps::Methods
6
8
 
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
  require 'mercury/utils'
3
3
 
4
+ Utils = Mercury::Utils
5
+
4
6
  describe Utils do
5
7
  describe '::unsplat' do
6
8
  it 'allows args to be provided in splatted form' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mercury_amqp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Winton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-09 00:00:00.000000000 Z
11
+ date: 2016-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler