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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8dcba3d11c7217ae50aa36d19f84c1a835734a22
4
- data.tar.gz: c6981dbd112701103491e1919fa2819a334aedc5
3
+ metadata.gz: 3ebcadc33e8f51d132862e8b648a6d4a2bd15cc0
4
+ data.tar.gz: 1626655dd9057674364a2e3ba8ced482e89b156e
5
5
  SHA512:
6
- metadata.gz: 887d99c878678e8f8a49dd71b8214fc4766ba5028ff65071f9c0634946256503e0aee8ff1c55ef37751aee730026a117db76d9f6424239333b4fcdbe56f6435b
7
- data.tar.gz: cf09e9f3710d6f726c9c58dbd08cb3087b14873aa9248a37f1d753d9c004a5a568d3a1204e14ccc2ed053f74f7be32e8d91764187e0e5cc8af64612f1b23f1b3
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
- # destination.balance += amount
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 doesn't have access to the other objects in the context. 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.
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 = :wrapper # also :wrap, :interface, or :module
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
- __getobj__
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 = :wrap
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
- __getobj__
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
- initialize :leader, :members
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
- @behaviors.instance_method(:#{meth}).bind(@object).call(*args, &block)
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 identity methods
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, @behaviors = object, __behaviors__
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
@@ -118,7 +118,7 @@ module Surrounded
118
118
 
119
119
  def rebind(options_hash)
120
120
  clear_instance_variables
121
- initialize(options_hash.to_a)
121
+ initialize(options_hash)
122
122
  rescue ArgumentError
123
123
  initialize(*options_hash.values)
124
124
  self
@@ -1,5 +1,5 @@
1
1
  module Surrounded
2
- VERSION = "0.9.5"
2
+ VERSION = "0.9.6"
3
3
 
4
4
  def self.version
5
5
  VERSION
@@ -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.5
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-22 00:00:00.000000000 Z
11
+ date: 2015-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: triad