surrounded 0.9.5 → 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -8
- data/lib/surrounded/context/negotiator.rb +23 -11
- data/lib/surrounded/context.rb +1 -1
- data/lib/surrounded/version.rb +1 -1
- data/test/example_proxy_test.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ebcadc33e8f51d132862e8b648a6d4a2bd15cc0
|
4
|
+
data.tar.gz: 1626655dd9057674364a2e3ba8ced482e89b156e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 514db8e6ef0df0df0e9ffba94df4ea3217c6fd8eb37d4bc187913599695b4bfdfd5610062ffb8a31f700d884eef4ef91890204052906f60641ff164e46f19046
|
7
|
+
data.tar.gz: a982f5d589c10ca7984273f4ced59520252a8425b5266b35beca3e1fdd5e93823ec80ce65f2397fb460514625c2c9c6a1883e95d106c6e41906cfe28f6e4520b
|
data/README.md
CHANGED
@@ -553,8 +553,8 @@ Using the `role` method to define modules and classes takes care of the setup fo
|
|
553
553
|
role :source, :interface do
|
554
554
|
def transfer
|
555
555
|
self.balance -= amount
|
556
|
-
# not able to access destination
|
557
|
-
|
556
|
+
# not able to access destination unless the object playing source is Surrounded
|
557
|
+
destination.balance += amount
|
558
558
|
self
|
559
559
|
end
|
560
560
|
end
|
@@ -564,7 +564,7 @@ The `:interface` option is a special object which has all of the standard Object
|
|
564
564
|
|
565
565
|
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__`.
|
566
566
|
|
567
|
-
The downside of using an interface is that it is still a wrapper and it
|
567
|
+
The downside of using an interface is that it is still a wrapper and it only has access to the other objects in the context if the wrapped object already includes Surrounded. All of your defined role methods are executed in the context of the object playing the role, but the interface has it's own identity.
|
568
568
|
|
569
569
|
If you'd like to choose one and use it all the time, you can set the default:
|
570
570
|
|
@@ -572,13 +572,13 @@ If you'd like to choose one and use it all the time, you can set the default:
|
|
572
572
|
class MoneyTransfer
|
573
573
|
extend Surrounded::Context
|
574
574
|
|
575
|
-
self.default_role_type = :
|
575
|
+
self.default_role_type = :interface # also :wrap, :wrapper, or :module
|
576
576
|
|
577
577
|
role :source do
|
578
578
|
def transfer
|
579
579
|
self.balance -= amount
|
580
580
|
destination.balance += amount
|
581
|
-
|
581
|
+
self
|
582
582
|
end
|
583
583
|
end
|
584
584
|
end
|
@@ -587,7 +587,7 @@ end
|
|
587
587
|
Or, if you like, you can choose the default for your entire project:
|
588
588
|
|
589
589
|
```ruby
|
590
|
-
Surrounded::Context.default_role_type = :
|
590
|
+
Surrounded::Context.default_role_type = :interface
|
591
591
|
|
592
592
|
class MoneyTransfer
|
593
593
|
extend Surrounded::Context
|
@@ -596,7 +596,7 @@ class MoneyTransfer
|
|
596
596
|
def transfer
|
597
597
|
self.balance -= amount
|
598
598
|
destination.balance += amount
|
599
|
-
|
599
|
+
self
|
600
600
|
end
|
601
601
|
end
|
602
602
|
end
|
@@ -614,7 +614,9 @@ would be given behavior from a `Member` behavior module or class if you create o
|
|
614
614
|
|
615
615
|
```ruby
|
616
616
|
class Organization
|
617
|
-
|
617
|
+
extend Surrounded::Context
|
618
|
+
|
619
|
+
initialize_without_keywords :leader, :members
|
618
620
|
|
619
621
|
role :members do
|
620
622
|
# special behavior for the collection
|
@@ -626,6 +628,15 @@ class Organization
|
|
626
628
|
end
|
627
629
|
```
|
628
630
|
|
631
|
+
## Reusing context objects
|
632
|
+
|
633
|
+
If you create a context object and need to use the same type of object with new role players, you may use the `rebind` method. It will clear any instance_variables from your context object and map the given objects to their names:
|
634
|
+
|
635
|
+
```ruby
|
636
|
+
context = Employment.new(current_user, the_boss)
|
637
|
+
context.rebind(employee: another_user, boss: someone_else) # same context, new players
|
638
|
+
```
|
639
|
+
|
629
640
|
## Overview in code
|
630
641
|
|
631
642
|
Here's a view of the possibilities in code.
|
@@ -747,6 +758,19 @@ class ActiviatingAccount
|
|
747
758
|
forward_triggers :role_name, :list, :of, :methods, :to, :forward
|
748
759
|
forwarding [:list, :of, :methods, :to, :forward] => :role_name
|
749
760
|
end
|
761
|
+
|
762
|
+
# with keyword_initialize (will be changed to initialize)
|
763
|
+
context = ActiviatingAccount.new(activator: some_object, account: some_account)
|
764
|
+
# with initialize (this will be moved to initialize_without_keywords)
|
765
|
+
context = ActiviatingAccount.new(some_object, some_account)
|
766
|
+
context.triggers # => lists a Set of triggers
|
767
|
+
# when using protect_triggers
|
768
|
+
context.triggers # => lists a Set of triggers which may currently be called
|
769
|
+
context.triggers # => lists a Set of all triggers (the same as if protect_triggers was _not_ used)
|
770
|
+
context.allow?(:trigger_name) # => returns a boolean if the trigger may be run
|
771
|
+
|
772
|
+
# reuse the context object with new role players
|
773
|
+
context.rebind(activator: another_object, account: another_account)
|
750
774
|
```
|
751
775
|
|
752
776
|
## Dependencies
|
@@ -7,16 +7,19 @@ module Surrounded
|
|
7
7
|
# This prevents hits to method_missing.
|
8
8
|
def for_role(mod)
|
9
9
|
klass = Class.new(self)
|
10
|
+
# Define access to the provided module
|
11
|
+
klass.send(:define_method, :__behaviors__) do
|
12
|
+
mod
|
13
|
+
end
|
14
|
+
# For each method in the module, directly forward to the wrapped object to
|
15
|
+
# circumvent method_missing
|
10
16
|
mod.instance_methods(false).each do |meth|
|
11
17
|
num = __LINE__; klass.class_eval %{
|
12
18
|
def #{meth}(*args, &block)
|
13
|
-
|
19
|
+
__behaviors__.instance_method(:#{meth}).bind(@object).call(*args, &block)
|
14
20
|
end
|
15
21
|
}, __FILE__, num
|
16
22
|
end
|
17
|
-
klass.send(:define_method, :__behaviors__) do
|
18
|
-
mod
|
19
|
-
end
|
20
23
|
klass
|
21
24
|
end
|
22
25
|
end
|
@@ -27,17 +30,31 @@ module Surrounded
|
|
27
30
|
|
28
31
|
reserved_methods = (identity + method_access).join('|')
|
29
32
|
|
30
|
-
# Remove all methods except the
|
33
|
+
# Remove all methods except the reserved methods
|
31
34
|
instance_methods.reject{ |m|
|
32
35
|
m.to_s =~ /#{reserved_methods}/
|
33
36
|
}.each do |meth|
|
34
37
|
undef_method meth
|
35
38
|
end
|
36
39
|
|
40
|
+
include Surrounded
|
41
|
+
|
37
42
|
private
|
38
43
|
|
44
|
+
# Store the context in the wrapped object if it can do so
|
45
|
+
def store_context(&block)
|
46
|
+
if @object.respond_to?(__method__, true)
|
47
|
+
@object.send(__method__, &block)
|
48
|
+
else
|
49
|
+
super
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
# These only differ in the message they send
|
54
|
+
alias remove_context store_context
|
55
|
+
|
39
56
|
def initialize(object)
|
40
|
-
@object
|
57
|
+
@object = object
|
41
58
|
end
|
42
59
|
|
43
60
|
def method_missing(meth, *args, &block)
|
@@ -48,10 +65,5 @@ module Surrounded
|
|
48
65
|
@object.respond_to?(meth, include_private)
|
49
66
|
end
|
50
67
|
end
|
51
|
-
|
52
|
-
# The method_missing definition from Surrounded will apply
|
53
|
-
# before the one defined above. This allows the methods for
|
54
|
-
# the objects in the context to work properly
|
55
|
-
Negotiator.send(:prepend, Surrounded)
|
56
68
|
end
|
57
69
|
end
|
data/lib/surrounded/context.rb
CHANGED
data/lib/surrounded/version.rb
CHANGED
data/test/example_proxy_test.rb
CHANGED
@@ -87,6 +87,10 @@ describe ProxyContext do
|
|
87
87
|
assert_equal :talking_to_others, context.get_admin_method.name
|
88
88
|
end
|
89
89
|
|
90
|
+
it 'allows Surrounded objects to interact with others' do
|
91
|
+
assert context.rebind(user: User.new('Surrounded'), task: task).talking
|
92
|
+
end
|
93
|
+
|
90
94
|
it 'works with frozen and primitive objects' do
|
91
95
|
context.rebind(admin: "brrr".freeze, task: task)
|
92
96
|
assert context.get_admin_method
|
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.9.
|
4
|
+
version: 0.9.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "'Jim Gay'"
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: triad
|