mixit 0.4.0 → 0.5.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.
data/README.md CHANGED
@@ -37,9 +37,11 @@ __WHY?__
37
37
 
38
38
  __EXAMPLES__
39
39
 
40
- Temporarily mix 'SomeModule' onto the 'self' referenced by _block_:
40
+ __1.__
41
41
 
42
- Mixit.temporarily SomeModule, :scope => self do
42
+ Temporarily mix 'SomeModule' onto 'self' (non-thread safe).
43
+
44
+ Mixit.temporarily :modules => [SomeModule], :scope => self do
43
45
  p self.class # => Object
44
46
  p respond_to?(:some_mixed_method) # => true
45
47
  end
@@ -47,6 +49,23 @@ Temporarily mix 'SomeModule' onto the 'self' referenced by _block_:
47
49
  p self.class # => Object
48
50
  p respond_to?(:some_mixed_method) # => false
49
51
 
52
+ __2.__
53
+
54
+ Temporarily mix 'SomeModule' onto 'self' (thread-safe - **per thread**)
55
+
56
+ A clone of the extended scope is passed as a argument to the receiving block.
57
+ Any state created by your mixed-in module(s) is lost to the original scope.
58
+ Any existing state mutated by your mixed-in module(s) will propagate back
59
+ to the original scope.
60
+
61
+ You should be careful, as always.
62
+
63
+ Mixit.temporarily :modules => [SomeModule], :scope => self do |extended|
64
+ p extended.class # => Object
65
+ p extended.respond_to?(:some_mixed_method) # => true
66
+ end
67
+
68
+
50
69
  __INSTALL__
51
70
 
52
71
  gem install mixit
data/lib/mixit/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Mixit
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/mixit.rb CHANGED
@@ -1,77 +1,68 @@
1
- require "mixit/core_ext/object"
2
1
  require "mixit/version"
3
2
 
4
3
  class Mixit
5
4
 
6
- class << self
5
+ class << self
7
6
  #
8
- # @overload mix(*modules, options, &block)
9
- # Temporarily extends a scope with methods from __modules__.
7
+ # Temporarily extends a scope with instance methods from modules.
10
8
  #
11
- # @param [Module] modules
12
- # A variable number of modules to extend the scope with.
13
- #
14
- # @param [Hash] options
9
+ # @param opts
10
+ # (see Mixit#initialize)
15
11
  #
16
- # @option options [Binding, Proc, Object] :scope
17
- # The scope to extend.
18
- #
19
- # @param block
20
- # (see Mixit#mix!)
12
+ # @option opts
13
+ # (see Mixit#initialize)
21
14
  #
22
- # @yieldparam object
23
- # (see Mixit#mix!)
24
- #
25
- # @raise [ArgumentError]
26
- # If the :scope option is missing.
15
+ # @param block
16
+ # (see Mixit#temporarily)
17
+ #
18
+ # @yieldparam object
19
+ # (see Mixit#temporarily)
27
20
  #
28
- # @return [void]
21
+ # @return
22
+ # (see Mixit#temporarily)
29
23
  #
30
- def mix(*args, &block)
31
- options = args.pop
32
- modules = args
33
-
34
- if options.has_key?(:scope)
35
- scope = options[:scope]
36
- else
37
- raise ArgumentError, 'missing :scope option.'
38
- end
39
-
40
- new(scope, modules).mix!(&block)
24
+ def temporarily opts, &block
25
+ mixit = new(opts)
26
+ mixit.temporarily(&block)
41
27
  end
42
- alias_method :temporarily, :mix
43
28
  end
44
29
 
45
30
  #
46
31
  # @return [Array<Module>]
47
- # An Array of Module objects.
48
- #
32
+ # An Array of modules to extend a scope with.
33
+ #
49
34
  attr_reader :modules
50
35
 
51
36
  #
52
37
  # @return [Object]
53
- # The scope.
38
+ # The scope to extend.
54
39
  #
55
40
  attr_reader :scope
56
41
 
57
42
  #
58
- # @param [Binding, Proc, Object] scope
59
- # A scope to extend.
43
+ # @param [Hash] opts
44
+ # A Hash of options.
45
+ #
46
+ # @option opts [Object] :scope
47
+ # The scope to extend.
48
+ #
49
+ # @option opts [Module] :modules
50
+ # An Array of modules to extend a scope with.
60
51
  #
61
- # @param [Array<Module>] modules
62
- # An Array of Module objects.
52
+ # @raise [ArgumentError]
53
+ # If the :scope option is missing.
63
54
  #
64
- def initialize scope, modules
65
- @modules = modules
55
+ def initialize opts
66
56
  @clones = []
57
+ @modules = opts[:modules]
67
58
 
68
- case scope
59
+ case opts[:scope]
69
60
  when Binding
70
- @scope = scope.eval "self"
61
+ @scope = opts[:scope].eval "self"
71
62
  when Proc
72
- @scope = scope.binding.eval "self"
63
+ @scope = opts[:scope].binding.eval "self"
73
64
  else
74
- @scope = scope
65
+ @scope = opts[:scope]
75
66
  end
76
67
  end
77
68
 
@@ -84,47 +75,32 @@ class Mixit
84
75
  # @yieldparam [Object] object
85
76
  # Yields a clone of the extended object (Optional).
86
77
  #
87
- # @return [void]
78
+ # @return [Object]
79
+ # Returns the return value of 'block'.
88
80
  #
89
- def mix! &block
81
+ def temporarily &block
90
82
  if block.arity == 1
91
- block.call extend!(true)
83
+ value = block.call extend_scope!(:clone => true)
92
84
  else
93
85
  begin
94
- extend!(false).instance_eval(&block)
86
+ value = extend_scope!(:clone => false).instance_eval(&block)
95
87
  ensure
96
88
  remove_methods!
97
89
  trigger_callback!
98
90
  end
99
91
  end
92
+
93
+ value
100
94
  end
101
95
 
102
- #
103
- # Extends {#scope} with the methods from {#modules modules}.
104
- #
105
- # @param [Boolean] to_be_cloned
106
- # If true, a clone of the scope is extended.
107
- #
108
- # @return [Object]
109
- # Returns the extended object.
110
- #
111
- def extend! clone_scope
112
- if clone_scope
113
- scope = @scope.clone
114
- else
115
- scope = @scope
116
- end
96
+ private
117
97
 
98
+ def extend_scope! options
99
+ options[:clone] ? (scope = @scope.clone) : (scope = @scope)
118
100
  @clones = @modules.map(&:clone)
119
101
  @clones.inject(scope) { |obj, mod| obj.extend(mod) }
120
102
  end
121
- private :extend!
122
103
 
123
- #
124
- # Remove methods used to extend {#scope} from module(s).
125
- #
126
- # @return [void]
127
- #
128
104
  def remove_methods!
129
105
  @clones.each do |clone|
130
106
  clone.instance_methods(false).each do |meth|
@@ -132,13 +108,7 @@ class Mixit
132
108
  end
133
109
  end
134
110
  end
135
- private :remove_methods!
136
111
 
137
- #
138
- # Calls cleanup! on module(s) used to extend a scope.
139
- #
140
- # @return [void]
141
- #
142
112
  def trigger_callback!
143
113
  @clones.each do |clone|
144
114
  if clone.respond_to?(:cleanup!)
@@ -146,7 +116,6 @@ class Mixit
146
116
  end
147
117
  end
148
118
  end
149
- private :trigger_callback!
150
119
 
151
120
  end
152
121
 
data/test/test_mixit.rb CHANGED
@@ -13,7 +13,7 @@ context Mixit do
13
13
  it 'must provide access to mixed-in methods' do
14
14
  block = proc { }
15
15
 
16
- Mixit.mix(@module, :scope => block) do
16
+ Mixit.temporarily :modules => [@module], :scope => block do
17
17
  callme.must_equal(:ok)
18
18
  end
19
19
  end
@@ -22,7 +22,7 @@ context Mixit do
22
22
  block = proc { }
23
23
  local = :ok
24
24
 
25
- Mixit.mix(@module, :scope => block) do
25
+ Mixit.temporarily :modules => [@module], :scope => block do
26
26
  local.must_equal(:ok)
27
27
  end
28
28
  end
@@ -31,7 +31,7 @@ context Mixit do
31
31
  def callme_() :ok end
32
32
  block = proc { }
33
33
 
34
- Mixit.mix(@module, :scope => block) do
34
+ Mixit.temporarily :modules => [@module], :scope => block do
35
35
  callme_.must_equal(:ok)
36
36
  end
37
37
  end
@@ -45,7 +45,7 @@ context Mixit do
45
45
  end
46
46
  end
47
47
 
48
- Mixit.mix(@module, :scope => block) do
48
+ Mixit.temporarily :modules => [@module], :scope => block do
49
49
  @ok = :no
50
50
  end
51
51
 
@@ -55,7 +55,7 @@ context Mixit do
55
55
  it 'must remove methods added by mixed-in modules.' do
56
56
  block = proc {}
57
57
 
58
- Mixit.mix(@module, :scope => block) do
58
+ Mixit.temporarily :modules => [@module], :scope => block do
59
59
  nil
60
60
  end
61
61
 
@@ -67,7 +67,7 @@ context Mixit do
67
67
  it 'must provide access to mixed-in methods.' do
68
68
  block = proc {}
69
69
 
70
- Mixit.mix(@module, :scope => block) do |receiver|
70
+ Mixit.temporarily :modules => [@module], :scope => block do |receiver|
71
71
  receiver.callme.must_equal(:ok)
72
72
  end
73
73
  end
@@ -75,7 +75,7 @@ context Mixit do
75
75
  it 'must not extend the original receiver with mixed-in methods.' do
76
76
  block = proc {}
77
77
 
78
- Mixit.mix(@module, :scope => block) do |receiver|
78
+ Mixit.temporarily :modules => [@module], :scope => block do |receiver|
79
79
  respond_to?(:callme).must_equal(false)
80
80
  end
81
81
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-26 00:00:00.000000000 Z
12
+ date: 2011-12-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70097654179640 !ruby/object:Gem::Requirement
16
+ requirement: &70177892499080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.9.2
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70097654179640
24
+ version_requirements: *70177892499080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &70097654179140 !ruby/object:Gem::Requirement
27
+ requirement: &70177892498580 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '2.5'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70097654179140
35
+ version_requirements: *70177892498580
36
36
  description: Temporarily extend the calling scope of a block with instance methods
37
37
  from a module.
38
38
  email:
@@ -49,7 +49,6 @@ files:
49
49
  - README.md
50
50
  - Rakefile
51
51
  - lib/mixit.rb
52
- - lib/mixit/core_ext/object.rb
53
52
  - lib/mixit/version.rb
54
53
  - mixit.gemspec
55
54
  - test/setup.rb
@@ -68,7 +67,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
67
  version: '0'
69
68
  segments:
70
69
  - 0
71
- hash: -1392924086282936836
70
+ hash: -3096325220678410006
72
71
  required_rubygems_version: !ruby/object:Gem::Requirement
73
72
  none: false
74
73
  requirements:
@@ -77,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
76
  version: '0'
78
77
  segments:
79
78
  - 0
80
- hash: -1392924086282936836
79
+ hash: -3096325220678410006
81
80
  requirements: []
82
81
  rubyforge_project: mixit
83
82
  rubygems_version: 1.8.11
@@ -1,3 +0,0 @@
1
- def Mix *args, &block
2
- Mixit.mix(*args, &block)
3
- end