README.md in surrounded-0.2.1 vs README.md in surrounded-0.3.0
- old
+ new
@@ -69,11 +69,11 @@
```ruby
class MyEnvironment
extend Surrounded::Context
- setup(:employee, :boss)
+ initialize(:employee, :boss)
module Employee
# extra behavior here...
end
end
@@ -95,11 +95,11 @@
With that, all instances of `User` have implicit access to their surroundings.
_Yeah... How?_
-Via `method_missing` those `User` instances can access a `context` object stored in `Thread.current`. I didn't mention how the context is set, however.
+Via `method_missing` those `User` instances can access a `context` object it stores in a `@__surroundings__` collection. I didn't mention how the context is set, however.
Your environment will have methods of it's own that will trigger actions on the objects inside, but we need those trigger methods to set the environment instance as the current context so that the objects it contains can access them.
Here's an example of what we want:
@@ -190,11 +190,11 @@
extend Surrounded::Context
apply_roles_on(:trigger) # this is the default
# apply_roles_on(:initialize) # set this to apply behavior from the start
- setup(:activator, :account)
+ initialize(:activator, :account)
module Activator
def some_behavior; end
end
@@ -225,9 +225,41 @@
```ruby
context = ActiviatingAccount.new(current_user, Account.find(123))
context.do_something
current_user.some_behavior # NoMethodError
```
+
+## How's the performance?
+
+I haven't really tested yet, but there are several ways you can add behavior to your objects.
+
+There are a few defaults built in.
+
+1. If you define modules for the added behavior, the code will run `object.extend(RoleInterface)`
+2. If you are using [casting](http://github.com/saturnflyer/casting), the code will run `object.cast_as(RoleInterface)`
+3. If you would rather use wrappers you can define classes and the code will run `RoleInterface.new(object)` and assumes that the `new` method takes 1 argument. You'll need to remember to `include Surrounded` in your classes, however.
+4. If you want to use wrappers but would rather not muck about with including modules and whatnot, you can define them like this:
+
+```
+class SomeContext
+ extend Surrounded::Context
+
+ initialize(:admin, :user)
+
+ wrap :admin do
+ # special methods defined here
+ end
+```
+
+The `wrap` method will create a class of the given name (`Admin` in this case) and will inherit from `SimpleDelegator` from the Ruby standard library _and_ will `include Surrounded`.
+
+Lastly, there's a 5th option if you're using Ruby 2.x: `interface`.
+
+The `interface` method acts similarly to the `wrap` method in that it returns an object that is not actually the object you want. But an `interface` is different in that it will apply methods from a module instead of using methods defined in a SimpleDelegator subclass. How is that important? Well you are free to use things like instance variables in your methods because they will be executed in the context of the object. This is unlike methods in a SimpleDelegator where the wrapper maintains its own instance variables.
+
+_Which should I use?_
+
+Start with the default and see how it goes, then try another approach and measure the changes.
## Dependencies
The dependencies are minimal. The plan is to keep it that way but allow you to configure things as you need.