README.md in surrounded-0.9.5 vs README.md in surrounded-0.9.6
- old
+ new
@@ -551,54 +551,54 @@
# this uses a special interface object which pulls
# methods from a module and applies them to your object.
role :source, :interface do
def transfer
self.balance -= amount
- # not able to access destination
- # destination.balance += amount
+ # not able to access destination unless the object playing source is Surrounded
+ destination.balance += amount
self
end
end
```
The `:interface` option is a special object which has all of the standard Object methods removed (excepting ones like `__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.
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__`.
-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.
+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.
If you'd like to choose one and use it all the time, you can set the default:
```ruby
class MoneyTransfer
extend Surrounded::Context
- self.default_role_type = :wrapper # also :wrap, :interface, or :module
+ self.default_role_type = :interface # also :wrap, :wrapper, or :module
role :source do
def transfer
self.balance -= amount
destination.balance += amount
- __getobj__
+ self
end
end
end
```
Or, if you like, you can choose the default for your entire project:
```ruby
-Surrounded::Context.default_role_type = :wrap
+Surrounded::Context.default_role_type = :interface
class MoneyTransfer
extend Surrounded::Context
role :source do
def transfer
self.balance -= amount
destination.balance += amount
- __getobj__
+ self
end
end
end
```
@@ -612,11 +612,13 @@
be given the behaviors from a `Members` behavior module or class. Each item in your `members` collection
would be given behavior from a `Member` behavior module or class if you create one.
```ruby
class Organization
- initialize :leader, :members
+ extend Surrounded::Context
+
+ initialize_without_keywords :leader, :members
role :members do
# special behavior for the collection
end
@@ -624,10 +626,19 @@
# special behavior to be applied to each member in the collection
end
end
```
+## Reusing context objects
+
+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:
+
+```ruby
+context = Employment.new(current_user, the_boss)
+context.rebind(employee: another_user, boss: someone_else) # same context, new players
+```
+
## Overview in code
Here's a view of the possibilities in code.
```ruby
@@ -745,9 +756,22 @@
forward_trigger :role_name, :method_name
forward_trigger :role_name, :method_name, :alternative_trigger_name_for_method_name
forward_triggers :role_name, :list, :of, :methods, :to, :forward
forwarding [:list, :of, :methods, :to, :forward] => :role_name
end
+
+# with keyword_initialize (will be changed to initialize)
+context = ActiviatingAccount.new(activator: some_object, account: some_account)
+# with initialize (this will be moved to initialize_without_keywords)
+context = ActiviatingAccount.new(some_object, some_account)
+context.triggers # => lists a Set of triggers
+# when using protect_triggers
+context.triggers # => lists a Set of triggers which may currently be called
+context.triggers # => lists a Set of all triggers (the same as if protect_triggers was _not_ used)
+context.allow?(:trigger_name) # => returns a boolean if the trigger may be run
+
+# reuse the context object with new role players
+context.rebind(activator: another_object, account: another_account)
```
## Dependencies
The dependencies are minimal. The plan is to keep it that way but allow you to configure things as you need. The [Triad](http://github.com/saturnflyer/triad) project was written specifically to manage the mapping of roles and objects to the modules which contain the behaviors. It is used in Surrounded to keep track of role player, roles, and role constant names but it is not a hard requirement. You may implement your own but presently you'll need to dive into the implementation to fully understand how. Future updates may provide better support and guidance.