multiplexing_delegator 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ == 0.1.1 / 2008-01-26
2
+
3
+ * Switched the delegation accessor from :on to :across.
4
+ * Included Enumerable and will now treat methods to call on the delegated methods differently than methods Enumerable like #map, #inject, etc.
5
+ * Stopped deciding whether or not return to nils and are just returning whatever is available. User can compact if they do not want nils.
6
+
1
7
  == 0.1.0 / 2008-01-25
2
8
 
3
9
  * Birth to the MultiplexingDelegator!
data/README.txt CHANGED
@@ -21,16 +21,19 @@ accessors for a given object instance and aggregating the results.
21
21
  Example
22
22
  class Foo
23
23
  attr_accessor :baz, :bum
24
- multiplex :bar, :on => [:baz, :bum]
24
+ multiplex :bar, :across => [:baz, :bum]
25
25
  end
26
26
 
27
27
  foo = Foo.new
28
28
  foo.baz = 1
29
- foo.bum = ['boo']
29
+ foo.bum = 'boo'
30
30
  foo.bar.map => [1, 'boo']
31
+ foo.bar.each {|item| puts "Yo yo #{item}"}
32
+ => Yo yo 1
33
+ => Yo yo boo
31
34
 
32
35
  You can also proxy method calls to each of the delegated items and results
33
- will be aggregated.
36
+ will be aggregated. This was the actual impetus behind writing this little gem.
34
37
 
35
38
  Example
36
39
  class Goo
@@ -43,6 +46,22 @@ Example
43
46
  foo.bum = Goo.new('world')
44
47
  foo.bar.car => ['hello, 'world']
45
48
 
49
+ A feature of multiplex that you may not expect is that it will flatten
50
+ arrays to one-level deep so as to simulate a single stream of results. For
51
+ instance, using Foo from above:
52
+
53
+ foo = Foo.new
54
+ foo.baz = 'hello world'
55
+ foo.bum = ['how', 'are', 'you]
56
+ foo.bar.map => ['hello world', 'how', 'are', 'you']
57
+
58
+ However, multiplex will not flatten more than one level deep. For example:
59
+
60
+ foo = Foo.new
61
+ foo.baz = [['hello', 'world']]
62
+ foo.bum = [['how', 'are', 'you]]
63
+ foo.bar.map => [['hello', 'world'], ['how', 'are', 'you']]
64
+
46
65
  == REQUIREMENTS:
47
66
 
48
67
  Ruby 1.8.6 and above
@@ -1,9 +1,6 @@
1
- # class MultiplexingDelegator
2
- # VERSION = '0.1.0'
3
- # end
4
1
  module Glomp #:nodoc:
5
2
  module MultiplexingDelegator #:nodoc:
6
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
7
4
 
8
5
  # The multiplex class method is used to define a delegator method that
9
6
  # multiplexes calls to a method across many methods for an instance of an
@@ -16,12 +13,12 @@ module Glomp #:nodoc:
16
13
  # Example
17
14
  # class Foo
18
15
  # attr_accessor :baz, :bum
19
- # multiplex :bar, :on => [:baz, :bum]
16
+ # multiplex :bar, :across => [:baz, :bum]
20
17
  # end
21
18
  #
22
19
  # foo = Foo.new
23
20
  # foo.baz = 1
24
- # foo.bum = ['boo']
21
+ # foo.bum = 'boo'
25
22
  # foo.bar.map => [1, 'boo']
26
23
  # foo.bar.each {|item| puts "Yo yo #{item}"}
27
24
  # => Yo yo 1
@@ -41,9 +38,25 @@ module Glomp #:nodoc:
41
38
  # foo.bum = Goo.new('world')
42
39
  # foo.bar.car => ['hello, 'world']
43
40
  #
41
+ # A feature of multiplex that you may not expect is that it will flatten
42
+ # arrays to one-level deep so as to simulate a single stream of results. For
43
+ # instance, using Foo from above:
44
+ #
45
+ # foo = Foo.new
46
+ # foo.baz = 'hello world'
47
+ # foo.bum = ['how', 'are', 'you]
48
+ # foo.bar.map => ['hello world', 'how', 'are', 'you']
49
+ #
50
+ # However, multiplex will not flatten more than one level deep. For example:
51
+ #
52
+ # foo = Foo.new
53
+ # foo.baz = [['hello', 'world']]
54
+ # foo.bum = [['how', 'are', 'you]]
55
+ # foo.bar.map => [['hello', 'world'], ['how', 'are', 'you']]
56
+ #
44
57
  def multiplex(method, opts={})
45
58
  define_method(method) do
46
- @multiplexer ||= Multiplexer.new(method, self, opts[:on])
59
+ @multiplexer ||= Multiplexer.new(method, self, opts[:across])
47
60
  end
48
61
  end
49
62
 
@@ -52,6 +65,8 @@ module Glomp #:nodoc:
52
65
  end
53
66
 
54
67
  class Multiplexer < BlankSlate
68
+ include Enumerable
69
+
55
70
  def initialize(name, target, on=[])
56
71
  @target = target
57
72
  @multiplexed = (array?(on) ? on : [on]).compact
@@ -61,18 +76,30 @@ module Glomp #:nodoc:
61
76
  end
62
77
  end
63
78
 
64
- def method_missing(sym, *args, &block)
65
- @multiplexed.inject([]) do |acc, proxy_to|
66
- proxy_target = @target.send(proxy_to)
67
- if proxy_target
68
- val = proxy_target.send(sym, *args, &block)
69
- acc = acc.send((array?(val) ? :+ : :<<), val)
79
+ def each(&block)
80
+ multiplexed_each do |proxy_target|
81
+ if array?(proxy_target)
82
+ proxy_target.each {|proxied_value| yield(proxied_value)}
83
+ else
84
+ yield(proxy_target)
70
85
  end
71
- acc
72
86
  end
73
87
  end
88
+
89
+ def method_missing(sym, *args, &block)
90
+ results = []
91
+ multiplexed_each do |proxy_target|
92
+ proxy_value = proxy_target.send(sym, *args, &block) if proxy_target
93
+ results.send((array?(proxy_value) ? :+ : :<<), proxy_value)
94
+ end
95
+ results
96
+ end
74
97
 
75
98
  private
99
+ def multiplexed_each(&block)
100
+ @multiplexed.each { |proxy_to| yield(@target.send(proxy_to))}
101
+ end
102
+
76
103
  def array?(obj) obj.kind_of?(Array); end
77
104
  end
78
105
 
@@ -1,6 +1,9 @@
1
1
  require 'multiplexing_delegator'
2
2
  require 'test/unit'
3
3
 
4
+ require 'rubygems'
5
+ require 'mocha'
6
+
4
7
  class Foo
5
8
  attr_accessor :bar
6
9
  def initialize(bar) @bar = bar; end
@@ -12,14 +15,29 @@ end
12
15
 
13
16
  class Family
14
17
  attr_accessor :adults, :children, :pets
15
- multiplex :members, :on => [:adults, :children, :pets]
18
+ multiplex :members, :across => [:adults, :children, :pets]
16
19
  end
17
20
 
18
21
  class TestMultiplexingDelegator < Test::Unit::TestCase
19
22
 
20
- def test_multiplex_returns_empty_array_when_nothing_to_aggregate
23
+ def test_should_only_create_one_multiplex_instance_per_object_instance
24
+ family = Family.new
25
+ assert_same family.members.__id__, family.members.__id__
26
+ assert_not_equal Family.new.members.__id__, family.members.__id__
27
+ end
28
+
29
+ def test_multiplexer_should_include_single_element_number_returns
30
+ family = Family.new
31
+ family.adults = 1; family.children = 2; family.pets = 3
32
+ assert_equal [1, 2, 3], family.members.map
33
+ end
34
+
35
+ def test_should_include_single_element_returns
21
36
  family = Family.new
22
- assert_equal [], family.members.map
37
+ family.adults = 'mom'
38
+ family.children = ['thing 1', 'thing 2']
39
+ family.pets = 'dog'
40
+ assert_equal ['mom'] + family.children + ['dog'], family.members.map
23
41
  end
24
42
 
25
43
  def test_multiplex_returns_flat_array_when_aggregating
@@ -31,26 +49,17 @@ class TestMultiplexingDelegator < Test::Unit::TestCase
31
49
  family.members.map
32
50
  end
33
51
 
34
- def test_should_only_create_one_multiplex_instance_per_object_instance
52
+ def test_multiplex_returns_array_of_nils_when_nothing_to_aggregate
35
53
  family = Family.new
36
- assert_same family.members.__id__, family.members.__id__
37
- assert_not_equal Family.new.members.__id__, family.members.__id__
54
+ assert_equal [nil, nil, nil], family.members.map
38
55
  end
39
56
 
40
- def test_should_include_single_element_returns
41
- family = Family.new
42
- family.adults = 'mom'
43
- family.children = ['thing 1', 'thing 2']
44
- family.pets = 'dog'
45
- assert_equal ['mom'] + family.children + ['dog'], family.members.map
46
- end
47
-
48
- def test_should_ignore_nil_values
57
+ def test_should_not_ignore_nil_values_when_enumerable_kicks_in
49
58
  family = Family.new
50
59
  family.adults = nil
51
60
  family.children = ['superfudge']
52
61
  family.pets = 'dog'
53
- assert_equal ['superfudge', 'dog'], family.members.map
62
+ assert_equal [nil, 'superfudge', 'dog'], family.members.map
54
63
  end
55
64
 
56
65
  def test_should_accept_nil_array_values
@@ -58,7 +67,7 @@ class TestMultiplexingDelegator < Test::Unit::TestCase
58
67
  family.adults = [nil]
59
68
  family.children = [nil]
60
69
  family.pets = nil
61
- assert_equal [nil, nil], family.members.map
70
+ assert_equal [nil, nil, nil], family.members.map
62
71
  end
63
72
 
64
73
  def test_should_throw_no_method_found_when_calling_unknown_method_on_assoc
@@ -82,10 +91,18 @@ class TestMultiplexingDelegator < Test::Unit::TestCase
82
91
  assert_equal [1, 2, 3], family.members.bar
83
92
  end
84
93
 
94
+ def test_should_not_ignore_nil_proxies
95
+ family = Family.new
96
+ family.adults = Foo.new(1)
97
+ family.children = nil
98
+ family.pets = Foo.new(3)
99
+ assert_equal [1, nil, 3], family.members.bar
100
+ end
101
+
85
102
  def test_should_accept_non_array_values_for_on
86
103
  family = Family.new
87
104
  class << family
88
- multiplex :foo, :on => :children
105
+ multiplex :foo, :across => :children
89
106
  end
90
107
  family.children = Foo.new('howdy')
91
108
  assert_equal ['howdy'], family.foo.bar
@@ -94,7 +111,7 @@ class TestMultiplexingDelegator < Test::Unit::TestCase
94
111
  def test_should_bail_with_a_nil_on
95
112
  family = Family.new
96
113
  class << family
97
- multiplex :foo, :on => nil
114
+ multiplex :foo, :across => nil
98
115
  end
99
116
  assert_raise(::ArgumentError) do
100
117
  family.foo.map
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiplexing_delegator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Knowlden