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 +21 -2
- data/lib/mixit/version.rb +1 -1
- data/lib/mixit.rb +45 -76
- data/test/test_mixit.rb +7 -7
- metadata +8 -9
- data/lib/mixit/core_ext/object.rb +0 -3
data/README.md
CHANGED
@@ -37,9 +37,11 @@ __WHY?__
|
|
37
37
|
|
38
38
|
__EXAMPLES__
|
39
39
|
|
40
|
-
|
40
|
+
__1.__
|
41
41
|
|
42
|
-
|
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
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
|
-
#
|
9
|
-
# Temporarily extends a scope with methods from __modules__.
|
7
|
+
# Temporarily extends a scope with instance methods from modules.
|
10
8
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# @param [Hash] options
|
9
|
+
# @param opts
|
10
|
+
# (see Mixit#initialize)
|
15
11
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# @param block
|
20
|
-
# (see Mixit#mix!)
|
12
|
+
# @option opts
|
13
|
+
# (see Mixit#initialize)
|
21
14
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
15
|
+
# @param block
|
16
|
+
# (see Mixit#temporarily)
|
17
|
+
#
|
18
|
+
# @yieldparam object
|
19
|
+
# (see Mixit#temporarily)
|
27
20
|
#
|
28
|
-
#
|
21
|
+
# @return
|
22
|
+
# (see Mixit#temporarily)
|
29
23
|
#
|
30
|
-
def
|
31
|
-
|
32
|
-
|
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
|
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 [
|
59
|
-
# A
|
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
|
-
# @
|
62
|
-
#
|
52
|
+
# @raise [ArgumentError]
|
53
|
+
# If the :scope option is missing.
|
63
54
|
#
|
64
|
-
def initialize
|
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 [
|
78
|
+
# @return [Object]
|
79
|
+
# Returns the return value of 'block'.
|
88
80
|
#
|
89
|
-
def
|
81
|
+
def temporarily &block
|
90
82
|
if block.arity == 1
|
91
|
-
block.call
|
83
|
+
value = block.call extend_scope!(:clone => true)
|
92
84
|
else
|
93
85
|
begin
|
94
|
-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
+
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-
|
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: &
|
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: *
|
24
|
+
version_requirements: *70177892499080
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: minitest
|
27
|
-
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: *
|
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: -
|
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: -
|
79
|
+
hash: -3096325220678410006
|
81
80
|
requirements: []
|
82
81
|
rubyforge_project: mixit
|
83
82
|
rubygems_version: 1.8.11
|