surrounded 0.3.0 → 0.3.1
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.
- checksums.yaml +4 -4
- data/examples/rails.rb +5 -1
- data/lib/surrounded/README.md +209 -0
- data/lib/surrounded/context.rb +55 -6
- data/lib/surrounded/context/negotiator.rb +4 -4
- data/lib/surrounded/context_errors.rb +1 -0
- data/lib/surrounded/version.rb +1 -1
- data/test/role_context_method_test.rb +143 -0
- metadata +5 -3
- data/examples/wrappers.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06fdae60ee9aa6572db5ba8151e49bfba7257501
|
4
|
+
data.tar.gz: dbed795a64a2ed83a405725e4a0bbf826952cc32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b930aaf822c3a9b77c8fb9390e8dd32d64077b3ede2f6cd8f347f429b07ad8b60c899585cf1453a0c7359d3eab48af0b73c64f19a33a10213d5ce6cb2b27fcfe
|
7
|
+
data.tar.gz: 00d58b00643d05d17f4ece1f7b1092104f4747535fe67368441fcfe57f0a52d2ebc31a4fba39569601d7d99d37a321cedc8f7be3fe713d88ee7d687d71b0d5ff
|
data/examples/rails.rb
CHANGED
@@ -34,6 +34,10 @@ end
|
|
34
34
|
|
35
35
|
class SomethingController < ApplicationController
|
36
36
|
def create
|
37
|
-
|
37
|
+
surround(current_user, User.last).do_something
|
38
|
+
end
|
39
|
+
|
40
|
+
def surround(admin, other)
|
41
|
+
SomeUseCase.new(admin, other, self)
|
38
42
|
end
|
39
43
|
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
# Surrounded aims to make things simple and get out of your way.
|
2
|
+
|
3
|
+
Most of what you care about is defining the behavior of objects. How they interact is important.
|
4
|
+
The purpose of this library is to clear away the details of getting things setup.
|
5
|
+
|
6
|
+
You should read the [main README](../../README.md) to get the gist of what's going on, if you haven't.
|
7
|
+
|
8
|
+
When you get started, you'll probably be specifying things exactly how you want them. But you can easily make changes.
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
class MoneyTransfer
|
12
|
+
extend Surrounded::Context
|
13
|
+
|
14
|
+
def initialize(source, destination, amount)
|
15
|
+
@source = source.extend(Source)
|
16
|
+
@destination = destination
|
17
|
+
@amount = amount
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :source, :destination, :amount
|
21
|
+
private :source, :destination, :amount
|
22
|
+
|
23
|
+
def execute
|
24
|
+
source.transfer
|
25
|
+
end
|
26
|
+
|
27
|
+
module Source
|
28
|
+
def transfer
|
29
|
+
self.balance -= amount
|
30
|
+
destination.balance += amount
|
31
|
+
self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
That's a lot of setup just to create the `execute` and `transfer` methods.
|
38
|
+
|
39
|
+
Here's a shortened version:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class MoneyTransfer
|
43
|
+
extend Surrounded::Context
|
44
|
+
|
45
|
+
initialize(:source, :destination, :amount)
|
46
|
+
|
47
|
+
trigger :execute do
|
48
|
+
source.transfer
|
49
|
+
end
|
50
|
+
|
51
|
+
module Source
|
52
|
+
def transfer
|
53
|
+
self.balance -= amount
|
54
|
+
destination.balance += amount
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Now it's cleaned up a bit and is much easier to see what's important.
|
62
|
+
If you decide you want to try out wrappers, you can start making changes to use `SimpleDelegator` from the standard library, but you'll have to remember to 1) `include Surrounded` 2) to do the initialize yourself again and 3) return the correct object from your role method.
|
63
|
+
|
64
|
+
Simply by changing your mind to use `SimpleDelegator`, here's what you'll need to do:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
class MoneyTransfer
|
68
|
+
extend Surrounded::Context
|
69
|
+
|
70
|
+
def initialize(source, destination, amount)
|
71
|
+
@source = Source.new(source)
|
72
|
+
@destination = destination
|
73
|
+
@amount = amount
|
74
|
+
end
|
75
|
+
|
76
|
+
attr_reader :source, :destination, :amount
|
77
|
+
private :source, :destination, :amount
|
78
|
+
|
79
|
+
def execute
|
80
|
+
source.transfer
|
81
|
+
end
|
82
|
+
|
83
|
+
class Source < SimpleDelegator
|
84
|
+
include Surrounded
|
85
|
+
|
86
|
+
def transfer
|
87
|
+
self.balance -= amount
|
88
|
+
destination.balance += amount
|
89
|
+
__getobj__
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
Once again, it's big and ugly. But surrounded has your back; you can istead do this:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
class MoneyTransfer
|
98
|
+
extend Surrounded::Context
|
99
|
+
|
100
|
+
initialize(:source, :destination, :amount)
|
101
|
+
|
102
|
+
trigger :execute do
|
103
|
+
source.transfer
|
104
|
+
end
|
105
|
+
|
106
|
+
wrap :source do
|
107
|
+
def transfer
|
108
|
+
self.balance -= amount
|
109
|
+
destination.balance += amount
|
110
|
+
__getobj__
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
That's not much different from the module and it takes care of using `SimpleDelegator` and including `Surrounded` for you. If you want to make changing your approach even easier, you can use the `role` method instead.
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
class MoneyTransfer
|
120
|
+
extend Surrounded::Context
|
121
|
+
|
122
|
+
initialize(:source, :destination, :amount)
|
123
|
+
|
124
|
+
trigger :execute do
|
125
|
+
source.transfer
|
126
|
+
end
|
127
|
+
|
128
|
+
role :source, :wrap do
|
129
|
+
def transfer
|
130
|
+
self.balance -= amount
|
131
|
+
destination.balance += amount
|
132
|
+
__getobj__
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
This way you can swap between implementations:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
|
142
|
+
# this uses modules
|
143
|
+
role :source do
|
144
|
+
def transfer
|
145
|
+
self.balance -= amount
|
146
|
+
destination.balance += amount
|
147
|
+
self
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# this uses SimpleDelegator and Surrounded
|
152
|
+
role :source do
|
153
|
+
def transfer
|
154
|
+
self.balance -= amount
|
155
|
+
destination.balance += amount
|
156
|
+
__getobj__
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# this uses a special interface object which pulls
|
161
|
+
# methods from a module and applies them to your object.
|
162
|
+
role :source, :interface do
|
163
|
+
def transfer
|
164
|
+
self.balance -= amount
|
165
|
+
destination.balance += amount
|
166
|
+
self
|
167
|
+
end
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
The `:interface` option is a special object which has all of its methods removed (excepting `__send__` and `object_id`) so that other methods will be pulled from the ones that you define, or from the object it attempts to proxy.
|
172
|
+
|
173
|
+
Notice that the `:interface` allows you to return `self` whereas the `:wrap` acts more like a wrapper and forces you to deal with that shortcoming by using it's wrapped-object-accessor method: `__getobj__`.
|
174
|
+
|
175
|
+
If you'd like to choose one and use it all the time, you can set the default:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
class MoneyTransfer
|
179
|
+
extend Surrounded::Context
|
180
|
+
|
181
|
+
self.default_role_type = :interface # also :wrap, :wrapper, or :module
|
182
|
+
|
183
|
+
role :source do
|
184
|
+
def transfer
|
185
|
+
self.balance -= amount
|
186
|
+
destination.balance += amount
|
187
|
+
self
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
```
|
192
|
+
|
193
|
+
Or, if you like, you can choose the default for your entire project:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
Surrounded::Context.default_role_type = :interface
|
197
|
+
|
198
|
+
class MoneyTransfer
|
199
|
+
extend Surrounded::Context
|
200
|
+
|
201
|
+
role :source do
|
202
|
+
def transfer
|
203
|
+
self.balance -= amount
|
204
|
+
destination.balance += amount
|
205
|
+
self
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
```
|
data/lib/surrounded/context.rb
CHANGED
@@ -9,6 +9,14 @@ module Surrounded
|
|
9
9
|
base.singleton_class.send(:alias_method, :setup, :initialize)
|
10
10
|
end
|
11
11
|
|
12
|
+
def self.default_role_type
|
13
|
+
@default_role_type ||= :module
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.default_role_type=(type)
|
17
|
+
@default_role_type = type
|
18
|
+
end
|
19
|
+
|
12
20
|
def new(*)
|
13
21
|
instance = super
|
14
22
|
instance.instance_variable_set('@__apply_role_policy', __apply_role_policy)
|
@@ -21,10 +29,37 @@ module Surrounded
|
|
21
29
|
|
22
30
|
private
|
23
31
|
|
32
|
+
def private_const_set(name, const)
|
33
|
+
const = const_set(name, const)
|
34
|
+
private_constant name
|
35
|
+
const
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_role_type
|
39
|
+
@default_role_type ||= Surrounded::Context.default_role_type
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_role_type=(type)
|
43
|
+
@default_role_type = type
|
44
|
+
end
|
45
|
+
|
46
|
+
def role(name, type=nil, &block)
|
47
|
+
role_type = type || default_role_type
|
48
|
+
case role_type
|
49
|
+
when :wrap, :wrapper then wrap(name, &block)
|
50
|
+
when :interface then interface(name, &block)
|
51
|
+
when :module then
|
52
|
+
mod_name = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
|
53
|
+
private_const_set(mod_name, Module.new(&block))
|
54
|
+
else
|
55
|
+
raise InvalidRoleType.new
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
24
59
|
def wrap(name, &block)
|
25
60
|
require 'delegate'
|
26
61
|
wrapper_name = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
|
27
|
-
klass =
|
62
|
+
klass = private_const_set(wrapper_name, Class.new(SimpleDelegator, &block))
|
28
63
|
klass.send(:include, Surrounded)
|
29
64
|
end
|
30
65
|
|
@@ -33,7 +68,7 @@ module Surrounded
|
|
33
68
|
class_basename = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
|
34
69
|
interface_name = class_basename + 'Interface'
|
35
70
|
|
36
|
-
behavior =
|
71
|
+
behavior = private_const_set(interface_name, Module.new(&block))
|
37
72
|
|
38
73
|
require 'surrounded/context/negotiator'
|
39
74
|
define_method(name) do
|
@@ -92,6 +127,12 @@ module Surrounded
|
|
92
127
|
@triggers << name
|
93
128
|
end
|
94
129
|
|
130
|
+
def role_const(name)
|
131
|
+
if const_defined?(name)
|
132
|
+
const_get(name)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
95
136
|
module InstanceMethods
|
96
137
|
def role?(name, &block)
|
97
138
|
return false unless role_map.role?(name)
|
@@ -128,7 +169,7 @@ module Surrounded
|
|
128
169
|
applicator = behavior.is_a?(Class) ? method(:add_class_interface) : method(:add_module_interface)
|
129
170
|
|
130
171
|
role_player = applicator.call(object, behavior)
|
131
|
-
map_role(role, role_module_basename(behavior), role_player)
|
172
|
+
map_role(role, role_module_basename(behavior), role_player) if behavior
|
132
173
|
role_player.store_context(self)
|
133
174
|
role_player
|
134
175
|
end
|
@@ -155,7 +196,7 @@ module Surrounded
|
|
155
196
|
object.remove_context
|
156
197
|
role_player = object.method(remover_name).call
|
157
198
|
|
158
|
-
map_role(role, role_module_basename(behavior), role_player)
|
199
|
+
map_role(role, role_module_basename(behavior), role_player) if behavior
|
159
200
|
|
160
201
|
role_player
|
161
202
|
end
|
@@ -170,8 +211,8 @@ module Surrounded
|
|
170
211
|
|
171
212
|
def traverse_map(applicator)
|
172
213
|
role_map.each do |role, mod_name, object|
|
173
|
-
if
|
174
|
-
applicator.call(role,
|
214
|
+
if role_const_defined?(mod_name)
|
215
|
+
applicator.call(role, role_const(mod_name), object)
|
175
216
|
end
|
176
217
|
end
|
177
218
|
end
|
@@ -199,6 +240,14 @@ module Surrounded
|
|
199
240
|
def role_module_basename(mod)
|
200
241
|
mod.to_s.split('::').last
|
201
242
|
end
|
243
|
+
|
244
|
+
def role_const(name)
|
245
|
+
self.class.send(:role_const, name)
|
246
|
+
end
|
247
|
+
|
248
|
+
def role_const_defined?(name)
|
249
|
+
self.class.const_defined?(name)
|
250
|
+
end
|
202
251
|
end
|
203
252
|
end
|
204
253
|
end
|
@@ -11,13 +11,13 @@ module Surrounded
|
|
11
11
|
|
12
12
|
private
|
13
13
|
|
14
|
-
def initialize(object,
|
15
|
-
@object, @
|
14
|
+
def initialize(object, behaviors)
|
15
|
+
@object, @behaviors = object, behaviors
|
16
16
|
end
|
17
17
|
|
18
18
|
def method_missing(meth, *args, &block)
|
19
|
-
if @
|
20
|
-
the_method = @
|
19
|
+
if @behaviors.instance_methods.include?(meth)
|
20
|
+
the_method = @behaviors.instance_method(meth)
|
21
21
|
the_method.bind(@object).call(*args, &block)
|
22
22
|
else
|
23
23
|
@object.send(meth, *args, &block)
|
data/lib/surrounded/version.rb
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe Surrounded::Context, '.role' do
|
5
|
+
class RoleContextTester
|
6
|
+
extend Surrounded::Context
|
7
|
+
|
8
|
+
role :admin do
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'modules' do
|
13
|
+
it 'creates a module' do
|
14
|
+
role = RoleContextTester.const_get('Admin')
|
15
|
+
refute_instance_of Class, role
|
16
|
+
assert_kind_of Module, role
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'marks the constant private' do
|
20
|
+
error = assert_raises(NameError){
|
21
|
+
RoleContextTester::Admin
|
22
|
+
}
|
23
|
+
assert_match /private constant/, error.message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class WrapperRoleContext
|
28
|
+
extend Surrounded::Context
|
29
|
+
|
30
|
+
role :admin, :wrap do
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'wrappers' do
|
36
|
+
it 'creates a wrapper' do
|
37
|
+
role = WrapperRoleContext.const_get('Admin')
|
38
|
+
assert_includes(role.ancestors, SimpleDelegator)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'marks the constant private' do
|
42
|
+
error = assert_raises(NameError){
|
43
|
+
WrapperRoleContext::Admin
|
44
|
+
}
|
45
|
+
assert_match /private constant/, error.message
|
46
|
+
end
|
47
|
+
end
|
48
|
+
if RedCard.check '2.0'
|
49
|
+
class InterfaceContext
|
50
|
+
extend Surrounded::Context
|
51
|
+
|
52
|
+
initialize(:admin, :other)
|
53
|
+
|
54
|
+
role :admin, :interface do
|
55
|
+
def hello
|
56
|
+
'hello from admin'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
trigger :admin_hello do
|
61
|
+
admin.hello
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Hello
|
66
|
+
def hello
|
67
|
+
'hello'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'interfaces' do
|
72
|
+
let(:context){
|
73
|
+
InterfaceContext.new(Hello.new, Hello.new)
|
74
|
+
}
|
75
|
+
it 'sets interface objects to use interface methods before singleton methods' do
|
76
|
+
assert_equal 'hello from admin', context.admin_hello
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'marks the inteface constant private' do
|
80
|
+
error = assert_raises(NameError){
|
81
|
+
InterfaceContext::AdminInterface
|
82
|
+
}
|
83
|
+
assert_match /private constant/, error.message
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'creates a private accessor method' do
|
87
|
+
assert_respond_to(context, :admin)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'unknown' do
|
93
|
+
it 'raises an error' do
|
94
|
+
assert_raises(Surrounded::Context::InvalidRoleType){
|
95
|
+
class UnknownRole
|
96
|
+
extend Surrounded::Context
|
97
|
+
|
98
|
+
role :admin, :unknown do
|
99
|
+
end
|
100
|
+
end
|
101
|
+
}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'custom default' do
|
106
|
+
it 'allows the use of custom default role types' do
|
107
|
+
class CustomDefaultWrap
|
108
|
+
extend Surrounded::Context
|
109
|
+
|
110
|
+
self.default_role_type = :wrap
|
111
|
+
apply_roles_on(:initialize)
|
112
|
+
|
113
|
+
initialize(:admin)
|
114
|
+
|
115
|
+
role :admin do
|
116
|
+
end
|
117
|
+
end
|
118
|
+
context = CustomDefaultWrap.new(Object.new)
|
119
|
+
assert_kind_of(SimpleDelegator, context.send(:admin))
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'allows the setting of custom default role time for all Surrounded::Contexts' do
|
123
|
+
begin
|
124
|
+
old_default = Surrounded::Context.default_role_type
|
125
|
+
Surrounded::Context.default_role_type = :wrap
|
126
|
+
class CustomGlobalDefault
|
127
|
+
extend Surrounded::Context
|
128
|
+
apply_roles_on(:initialize)
|
129
|
+
|
130
|
+
initialize(:admin)
|
131
|
+
|
132
|
+
role :admin do
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context = CustomGlobalDefault.new(Object.new)
|
137
|
+
assert_kind_of(SimpleDelegator, context.send(:admin))
|
138
|
+
ensure
|
139
|
+
Surrounded::Context.default_role_type = old_default
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surrounded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- '''Jim Gay'''
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: triad
|
@@ -81,8 +81,8 @@ files:
|
|
81
81
|
- README.md
|
82
82
|
- Rakefile
|
83
83
|
- examples/rails.rb
|
84
|
-
- examples/wrappers.rb
|
85
84
|
- lib/surrounded.rb
|
85
|
+
- lib/surrounded/README.md
|
86
86
|
- lib/surrounded/context.rb
|
87
87
|
- lib/surrounded/context/negotiator.rb
|
88
88
|
- lib/surrounded/context/role_map.rb
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- test/example_proxy_test.rb
|
93
93
|
- test/example_threaded_test.rb
|
94
94
|
- test/example_wrapper_test.rb
|
95
|
+
- test/role_context_method_test.rb
|
95
96
|
- test/surrounded_context_test.rb
|
96
97
|
- test/surrounded_test.rb
|
97
98
|
- test/test_helper.rb
|
@@ -123,6 +124,7 @@ test_files:
|
|
123
124
|
- test/example_proxy_test.rb
|
124
125
|
- test/example_threaded_test.rb
|
125
126
|
- test/example_wrapper_test.rb
|
127
|
+
- test/role_context_method_test.rb
|
126
128
|
- test/surrounded_context_test.rb
|
127
129
|
- test/surrounded_test.rb
|
128
130
|
- test/test_helper.rb
|
data/examples/wrappers.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# If you want to use wrappers, here's how you could
|
2
|
-
|
3
|
-
require 'surrounded/context'
|
4
|
-
require 'delegate'
|
5
|
-
class WrapperContext
|
6
|
-
extend Surrounded::Context
|
7
|
-
|
8
|
-
apply_roles_on(:trigger)
|
9
|
-
setup(:admin, :task)
|
10
|
-
|
11
|
-
class Admin < SimpleDelegator
|
12
|
-
def some_admin_method
|
13
|
-
puts 'hello from the admin wrapper!'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
trigger :do_something do
|
18
|
-
admin.some_admin_method
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def add_role_methods(obj, wrapper)
|
24
|
-
assign_role(role_name(wrapper), wrapper.new(obj))
|
25
|
-
end
|
26
|
-
|
27
|
-
def remove_role_methods(obj, wrapper)
|
28
|
-
# in this case, the obj is already wrapped
|
29
|
-
core_object = self.send(role_name(wrapper)).__getobj__
|
30
|
-
assign_role(role_name(wrapper), core_object)
|
31
|
-
end
|
32
|
-
|
33
|
-
def role_name(klass)
|
34
|
-
klass.name.split("::").last.gsub(/([A-Z])/){ "_#{$1.downcase}" }.sub(/^_/,'')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context = WrapperContext.new(Object.new, Object.new)
|
39
|
-
context.do_something
|