surrounded 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ var metas = document.getElementsByTagName('meta');
2
+ var i;
3
+ if (navigator.userAgent.match(/iPhone/i)) {
4
+ for (i=0; i<metas.length; i++) {
5
+ if (metas[i].name == "viewport") {
6
+ metas[i].content = "width=device-width, minimum-scale=1.0, maximum-scale=1.0";
7
+ }
8
+ }
9
+ document.addEventListener("gesturestart", gestureStart, false);
10
+ }
11
+ function gestureStart() {
12
+ for (i=0; i<metas.length; i++) {
13
+ if (metas[i].name == "viewport") {
14
+ metas[i].content = "width=device-width, minimum-scale=0.25, maximum-scale=1.6";
15
+ }
16
+ }
17
+ }
@@ -5,16 +5,24 @@ require 'surrounded/shortcuts'
5
5
 
6
6
  # Some features are only available in versions of Ruby
7
7
  # where this method is true
8
- def module_method_rebinding?
9
- return @__module_method_rebinding__ if defined?(@__module_method_rebinding__)
10
- sample_method = Enumerable.instance_method(:to_a)
11
- @__module_method_rebinding__ = begin
12
- !!sample_method.bind(Object.new)
13
- rescue TypeError
14
- false
8
+ unless defined?(module_method_rebinding?)
9
+ def module_method_rebinding?
10
+ return @__module_method_rebinding__ if defined?(@__module_method_rebinding__)
11
+ sample_method = Enumerable.instance_method(:to_a)
12
+ @__module_method_rebinding__ = begin
13
+ !!sample_method.bind(Object.new)
14
+ rescue TypeError
15
+ false
16
+ end
15
17
  end
16
18
  end
17
19
 
20
+ # Extend your classes with Surrounded::Context to handle their
21
+ # initialization and application of behaviors to the role players
22
+ # passed into the constructor.
23
+ #
24
+ # The purpose of this module is to help you create context objects
25
+ # which encapsulate the interaction and behavior of objects inside.
18
26
  module Surrounded
19
27
  module Context
20
28
  def self.extended(base)
@@ -32,12 +40,16 @@ module Surrounded
32
40
  instance
33
41
  end
34
42
 
43
+ # Provides a Set of all available trigger methods where
44
+ # behaviors will be applied to the roles before execution
45
+ # and removed afterward.
35
46
  def triggers
36
47
  @triggers.dup
37
48
  end
38
49
 
39
50
  private
40
51
 
52
+ # Set the default type of implementation for role methods for all contexts.
41
53
  def self.default_role_type
42
54
  @default_role_type ||= :module
43
55
  end
@@ -47,7 +59,11 @@ module Surrounded
47
59
  end
48
60
 
49
61
  # Additional Features
62
+
63
+ # Provide the ability to create access control methods for your triggers.
50
64
  def protect_triggers; self.extend(::Surrounded::AccessControl); end
65
+
66
+ # Automatically create class methods for each trigger method.
51
67
  def shortcut_triggers; self.extend(::Surrounded::Shortcuts); end
52
68
 
53
69
  def private_const_set(name, const)
@@ -60,10 +76,12 @@ module Surrounded
60
76
  @default_role_type ||= Surrounded::Context.default_role_type
61
77
  end
62
78
 
79
+ # Set the default type of implementation for role method for an individual context.
63
80
  def default_role_type=(type)
64
81
  @default_role_type = type
65
82
  end
66
83
 
84
+ # Create a named behavior for a role using the standard library SimpleDelegator.
67
85
  def wrap(name, &block)
68
86
  require 'delegate'
69
87
  wrapper_name = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
@@ -73,6 +91,7 @@ module Surrounded
73
91
  alias_method :wrapper, :wrap
74
92
 
75
93
  if module_method_rebinding?
94
+ # Create an object which will bind methods to the role player
76
95
  def interface(name, &block)
77
96
  class_basename = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
78
97
  interface_name = class_basename + 'Interface'
@@ -80,12 +99,14 @@ module Surrounded
80
99
  behavior = private_const_set(interface_name, Module.new(&block))
81
100
 
82
101
  require 'surrounded/context/negotiator'
102
+ undef_method(name)
83
103
  define_method(name) do
84
104
  instance_variable_set("@#{name}", Negotiator.new(role_map.assigned_player(name), behavior))
85
105
  end
86
106
  end
87
107
  end
88
108
 
109
+ # Define behaviors for your role players
89
110
  def role(name, type=nil, &block)
90
111
  role_type = type || default_role_type
91
112
  if role_type == :module
@@ -108,6 +129,8 @@ module Surrounded
108
129
  @__apply_role_policy ||= :trigger
109
130
  end
110
131
 
132
+ # Shorthand for creating an instance level initialize method which
133
+ # handles the mapping of the given arguments to their named role.
111
134
  def initialize(*setup_args)
112
135
  private_attr_reader(*setup_args)
113
136
 
@@ -127,6 +150,22 @@ module Surrounded
127
150
  private(*method_names)
128
151
  end
129
152
 
153
+ # Creates a context instance method which will apply behaviors to role players
154
+ # before execution and remove the behaviors after execution.
155
+ #
156
+ # Alternatively you may define your own methods then declare them as triggers
157
+ # afterward.
158
+ #
159
+ # Example:
160
+ # trigger :some_event do
161
+ # # code here
162
+ # end
163
+ #
164
+ # def some_event
165
+ # # code here
166
+ # end
167
+ # trigger :some_event
168
+ #
130
169
  def trigger(*names, &block)
131
170
  if block.nil?
132
171
  names.each do |name|
@@ -180,12 +219,20 @@ module Surrounded
180
219
  end
181
220
 
182
221
  module InstanceMethods
222
+ # Check whether a given name is a role inside the context.
223
+ # The provided block is used to evaluate whether or not the caller
224
+ # is allowed to inquire about the roles.
183
225
  def role?(name, &block)
184
226
  return false unless role_map.role?(name)
185
- accessor = eval('self', block.binding)
227
+ accessor = block.binding.eval('self')
186
228
  role_map.role_player?(accessor) && role_map.assigned_player(name)
187
229
  end
188
230
 
231
+ # Check if a given object is a role player in the context.
232
+ def role_player?(obj)
233
+ role_map.role_player?(obj)
234
+ end
235
+
189
236
  def triggers
190
237
  self.class.triggers
191
238
  end
@@ -224,7 +271,7 @@ module Surrounded
224
271
 
225
272
  role_player = applicator.call(object, behavior)
226
273
  map_role(role, role_module_basename(behavior), role_player) if behavior
227
- role_player.store_context(self)
274
+ role_player.send(:store_context, self){}
228
275
  role_player
229
276
  end
230
277
 
@@ -247,7 +294,7 @@ module Surrounded
247
294
  remover_name = (module_removal_methods + unwrap_methods).find{|meth| object.respond_to?(meth) }
248
295
  return object if !remover_name
249
296
 
250
- object.remove_context
297
+ object.send(:remove_context) do; end
251
298
  role_player = object.method(remover_name).call
252
299
 
253
300
  map_role(role, role_module_basename(behavior), role_player) if behavior
@@ -271,18 +318,22 @@ module Surrounded
271
318
  end
272
319
  end
273
320
 
321
+ # List of possible methods to use to add behavior to an object from a module.
274
322
  def module_extension_methods
275
323
  [:cast_as, :extend]
276
324
  end
277
325
 
326
+ # List of possible methods to use to add behavior to an object from a wrapper.
278
327
  def wrap_methods
279
328
  [:new]
280
329
  end
281
330
 
331
+ # List of possible methods to use to remove behavior from an object with a module.
282
332
  def module_removal_methods
283
333
  [:uncast]
284
334
  end
285
335
 
336
+ # List of possible methods to use to remove behavior from an object with a wrapper.
286
337
  def unwrap_methods
287
338
  [:__getobj__]
288
339
  end
@@ -1,3 +1,3 @@
1
1
  module Surrounded
2
- VERSION = "0.7.3"
2
+ VERSION = "0.8.0"
3
3
  end
data/lib/surrounded.rb CHANGED
@@ -1,46 +1,32 @@
1
1
  require "surrounded/version"
2
2
  require "surrounded/context"
3
3
 
4
+ # This module should be added to objects which will enter
5
+ # into context objects.
6
+ #
7
+ # Its main purpose is to keep a reference to the context
8
+ # and to implement method_missing to handle the relationship
9
+ # to other objects in the context.
4
10
  module Surrounded
5
- def self.included(klass)
6
- klass.class_eval {
7
- extend Surrounded::Contextual
8
- }
9
- unless klass.is_a?(Class)
10
- def klass.extended(object)
11
- Surrounded.create_surroundings(object)
12
- end
13
- end
14
- end
15
11
 
16
- def self.extended(object)
17
- Surrounded.create_surroundings(object)
18
- end
12
+ private
19
13
 
20
- module Contextual
21
- def new(*args)
22
- instance = super
23
- Surrounded.create_surroundings(instance)
24
- instance
14
+ def store_context(ctxt, &block)
15
+ accessor = block.binding.eval('self')
16
+ if accessor.role_player?(self)
17
+ surroundings.unshift(ctxt)
25
18
  end
26
19
  end
27
20
 
28
- def store_context(ctxt)
29
- surroundings.unshift(ctxt)
30
- end
31
-
32
- def remove_context
33
- surroundings.shift
34
- end
35
-
36
- private
37
-
38
- def self.create_surroundings(obj)
39
- obj.instance_variable_set(:@__surroundings__, [])
21
+ def remove_context(&block)
22
+ accessor = block.binding.eval('self')
23
+ if accessor.role_player?(self)
24
+ surroundings.shift
25
+ end
40
26
  end
41
27
 
42
28
  def surroundings
43
- @__surroundings__
29
+ @__surroundings__ ||= []
44
30
  end
45
31
 
46
32
  def context
data/params.json ADDED
@@ -0,0 +1 @@
1
+ {"name":"Surrounded","tagline":"Gives an object implicit access to other objects in it's environment.","body":"# ![Surrounded](http://saturnflyer.github.io/surrounded/images/surrounded.png \"Surrounded\")\r\n## Bring your own complexity\r\n\r\n[![Build Status](https://travis-ci.org/saturnflyer/surrounded.png?branch=master)](https://travis-ci.org/saturnflyer/surrounded)\r\n[![Code Climate](https://codeclimate.com/github/saturnflyer/surrounded.png)](https://codeclimate.com/github/saturnflyer/surrounded)\r\n[![Coverage Status](https://coveralls.io/repos/saturnflyer/surrounded/badge.png)](https://coveralls.io/r/saturnflyer/surrounded)\r\n[![Gem Version](https://badge.fury.io/rb/surrounded.png)](http://badge.fury.io/rb/surrounded)\r\n\r\n# Surrounded aims to make things simple and get out of your way.\r\n\r\nMost of what you care about is defining the behavior of objects. How they interact is important.\r\nThe purpose of this library is to clear away the details of getting things setup and to allow you to make changes to the way you handle roles.\r\n\r\nThere are two main parts to this library. \r\n\r\n1. `Surrounded` gives objects an implicit awareness of other objects in their environments.\r\n2. `Surrounded::Context` helps you create objects which encapsulate other objects. These *are* the environments.\r\n\r\nFirst, take a look at creating contexts. This is where you'll spend most of your time.\r\n\r\n## Easily create encapsulated environments for your objects.\r\n\r\nTypical initialization of an environment, or a Context in DCI, has a lot of code. For example:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n\r\n attr_reader :employee, :boss\r\n private :employee, :boss\r\n def initialize(employee, boss)\r\n @employee = employee.extend(Employee)\r\n @boss = boss\r\n end\r\n\r\n module Employee\r\n # extra behavior here...\r\n end\r\nend\r\n```\r\n\r\nThis code allows the MyEnvironment class to create instances where it will have an `employee` and a `boss` role internally. These are set to `attr_reader`s and are made private.\r\n\r\nThe `employee` is extended with behaviors defined in the `Employee` module, and in this case there's no extra stuff for the `boss` so it doesn't get extended with anything.\r\n\r\nMost of the time you'll follow a pattern like this. Some objects will get extra behavior and some won't. The modules that you use to provide the behavior will match the names you use for the roles to which you assign objects.\r\n\r\nBy adding `Surrounded::Context` you can shortcut all this work.\r\n\r\n```ruby\r\nclass MyEnvironment\r\n extend Surrounded::Context\r\n \r\n initialize(:employee, :boss)\r\n\r\n module Employee\r\n # extra behavior here...\r\n end\r\nend\r\n```\r\n\r\nSurrounded gives you an `initialize` class method which does all the setup work for you.\r\n\r\n## Managing Roles\r\n\r\n_I don't want to use modules. Can't I use something like SimpleDelegator?_\r\n\r\nWell, it just so happens that you can. This code will work just fine:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n extend Surrounded::Context\r\n \r\n initialize(:employee, :boss)\r\n\r\n class Employee < SimpleDelegator\r\n # extra behavior here...\r\n end\r\nend\r\n```\r\n\r\nInstead of extending the `employee` object, Surrounded will run `Employee.new(employee)` to create the wrapper for you. You'll need to include the `Surrounded` module in your wrapper, but we'll get to that.\r\n\r\nBut the syntax can be even simpler than that if you want.\r\n\r\n```ruby\r\nclass MyEnvironment\r\n extend Surrounded::Context\r\n \r\n initialize(:employee, :boss)\r\n\r\n role :employee do\r\n # extra behavior here...\r\n end\r\nend\r\n```\r\n\r\nBy default, this code will create a module for you named `Employee`. If you want to use a wrapper, you can do this:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n extend Surrounded::Context\r\n \r\n initialize(:employee, :boss)\r\n\r\n wrap :employee do\r\n # extra behavior here...\r\n end\r\nend\r\n```\r\n\r\nBut if you're making changes and you decide to move from a module to a wrapper or from a wrapper to a module, you'll need to change that method call. Instead, you could just tell it which type of role to use:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n extend Surrounded::Context\r\n \r\n initialize(:employee, :boss)\r\n\r\n role :employee, :wrapper do\r\n # extra behavior here...\r\n end\r\nend\r\n```\r\n\r\nThe default available types are `:module`, `:wrap` or `:wrapper`, and `:interface`. We'll get to `interface` below. The `:wrap` and `:wrapper` types are the same and they'll both create classes which inherit from SimpleDelegator _and_ include Surrounded for you.\r\n\r\nThese are minor little changes which highlight how simple it is to use Surrounded.\r\n\r\n_Well... I want to use [Casting](https://github.com/saturnflyer/casting) so I get the benefit of modules without extending objects. Can I do that?_\r\n\r\nYup. The ability to use Casting is built-in. If the objects you provide to your context respond to `cast_as` then Surrounded will use that.\r\n\r\n_Ok. So is that it?_\r\n\r\nThere's a lot more. Let's look at the individual objects and what they need for this to be valuable...\r\n\r\n## Objects' access to their environments\r\n\r\nAdd `Surrounded` to your objects to give them awareness of other objects.\r\n\r\n```ruby\r\nclass User\r\n include Surrounded\r\nend\r\n```\r\n\r\nNow the `User` instances will be able to implicitly access objects in their environment.\r\n\r\nVia `method_missing` those `User` instances can access a `context` object it stores in an internal collection. \r\n\r\nInside of the `MyEnvironment` context we saw above, the `employee` and `boss` objects are instances of `User` for this example.\r\n\r\nBecause the `User` class includes `Surrounded`, the instances of that class will be able to access other objects in the same context implicitly.\r\n\r\nLet's make our context look like this:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n # other stuff from above is still here...\r\n\r\n def shove_it\r\n employee.quit\r\n end\r\n\r\n role :employee do\r\n def quit\r\n say(\"I'm sick of this place, #{boss.name}!\")\r\n stomp\r\n throw_papers\r\n say(\"I quit!\")\r\n end\r\n end\r\nend\r\n```\r\n\r\nWhat's happening in there is that when the `shove_it` method is called on the instance of `MyEnvironment`, the `employee` has the ability to refer to `boss` because it is in the same context, e.g. the same environment.\r\n\r\nThe behavior defined in the `Employee` module assumes that it may access other objects in it's local environment. The `boss` object, for example, is never explicitly passed in as an argument.\r\n\r\nWhat `Surrounded` does for us is to make the relationship between objects and gives them the ability to access each other. Adding new or different roles to the context now only requires that we add them to the context and nothing else. No explicit references must be passed to each individual method. The objects are aware of the other objects around them and can refer to them by their role name.\r\n\r\nI didn't mention how the context is set, however.\r\n\r\n## Tying objects together\r\n\r\nYour context will have methods of it's own which will trigger actions on the objects inside, but we need those trigger methods to set the accessible context for each of the contained objects.\r\n\r\nHere's an example of what we want:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n # other stuff from above is still here...\r\n\r\n def shove_it\r\n employee.store_context(self)\r\n employee.quit\r\n employee.remove_context\r\n end\r\n\r\n role :employee do\r\n def quit\r\n say(\"I'm sick of this place, #{boss.name}!\")\r\n stomp\r\n throw_papers\r\n say(\"I quit!\")\r\n end\r\n end\r\nend\r\n```\r\n\r\nNow that the `employee` has a reference to the context, it won't blow up when it hits `boss` inside that `quit` method.\r\n\r\nWe saw how we were able to clear up a lot of that repetitive work with the `initialize` method, so this is how we do it here:\r\n\r\n```ruby\r\nclass MyEnvironment\r\n # other stuff from above is still here...\r\n\r\n trigger :shove_it do\r\n employee.quit\r\n end\r\n\r\n role :employee do\r\n def quit\r\n say(\"I'm sick of this place, #{boss.name}!\")\r\n stomp\r\n throw_papers\r\n say(\"I quit!\")\r\n end\r\n end\r\nend\r\n```\r\n\r\nBy using this `trigger` keyword, our block is the code we care about, but internally the method is created to first set all the objects' current contexts.\r\n\r\nThe context will also store the triggers so that you can, for example, provide details outside of the environment about what triggers exist.\r\n\r\n```ruby\r\ncontext = MyEnvironment.new(current_user, the_boss)\r\ncontext.triggers #=> [:shove_it]\r\n```\r\n\r\nYou might find that useful for dynamically defining user interfaces.\r\n\r\nSometimes I'd rather not use this DSL, however. I want to just write regular methods. \r\n\r\nWe can do that too. You'll need to opt in to this by specifying `set_methods_as_triggers` for the context class.\r\n\r\n```ruby\r\nclass MyEnvironment\r\n # other stuff from above is still here...\r\n \r\n set_methods_as_triggers\r\n\r\n def shove_it\r\n employee.quit\r\n end\r\n\r\n role :employee do\r\n def quit\r\n say(\"I'm sick of this place, #{boss.name}!\")\r\n stomp\r\n throw_papers\r\n say(\"I quit!\")\r\n end\r\n end\r\nend\r\n```\r\n\r\nThis will allow you to write methods like you normally would. They are aliased internally with a prefix and the method name that you use is rewritten to add and remove the context for the objects in this context. The public API of your class remains the same, but the extra feature of wrapping your method is handled for you.\r\n\r\nThis will treat all instance methods defined on your context the same way, so be aware of that.\r\n\r\n## Where roles exist\r\n\r\nBy using `Surrounded::Context` you are declaring a relationship between the objects inside playing your defined roles.\r\n\r\nBecause all the behavior is defined internally and only relevant internally, those relationships don't exist outside of the environment.\r\n\r\nSurrounded makes all of your role modules and classes private constants. It's not a good idea to try to reuse behavior defined for one context in another area.\r\n\r\n## The role DSL\r\n\r\nUsing the `role` method to define modules and classes takes care of the setup for you. This way you can swap between implementations:\r\n\r\n```ruby\r\n\r\n # this uses modules\r\n role :source do\r\n def transfer\r\n self.balance -= amount\r\n destination.balance += amount\r\n self\r\n end\r\n end\r\n\r\n # this uses SimpleDelegator and Surrounded\r\n role :source, :wrap do\r\n def transfer\r\n self.balance -= amount\r\n destination.balance += amount\r\n __getobj__\r\n end\r\n end\r\n\r\n # this uses a special interface object which pulls\r\n # methods from a module and applies them to your object.\r\n role :source, :interface do\r\n def transfer\r\n self.balance -= amount\r\n destination.balance += amount\r\n self\r\n end\r\n end\r\n```\r\n\r\nThe `: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.\r\n\r\nNotice 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__`.\r\n\r\nIf you'd like to choose one and use it all the time, you can set the default:\r\n\r\n```ruby\r\nclass MoneyTransfer\r\n extend Surrounded::Context\r\n\r\n self.default_role_type = :interface # also :wrap, :wrapper, or :module\r\n\r\n role :source do\r\n def transfer\r\n self.balance -= amount\r\n destination.balance += amount\r\n self\r\n end\r\n end\r\nend\r\n```\r\n\r\nOr, if you like, you can choose the default for your entire project:\r\n\r\n```ruby\r\nSurrounded::Context.default_role_type = :interface\r\n\r\nclass MoneyTransfer\r\n extend Surrounded::Context\r\n\r\n role :source do\r\n def transfer\r\n self.balance -= amount\r\n destination.balance += amount\r\n self\r\n end\r\n end\r\nend\r\n```\r\n\r\n## Policies for the application of role methods\r\n\r\nThere are 2 approaches to applying new behavior to your objects.\r\n\r\nBy default your context will add methods to an object before a trigger is run\r\nand behaviors will be removed after the trigger is run.\r\n\r\nAlternatively you may set the behaviors to be added during the initialize method\r\nof your context.\r\n\r\nHere's how it works:\r\n\r\n```ruby\r\nclass ActiviatingAccount\r\n extend Surrounded::Context\r\n\r\n apply_roles_on(:trigger) # this is the default\r\n # apply_roles_on(:initialize) # set this to apply behavior from the start\r\n\r\n initialize(:activator, :account)\r\n\r\n role :activator do\r\n def some_behavior; end\r\n end\r\n\r\n def non_trigger_method\r\n activator.some_behavior # not available unless you apply roles on initialize\r\n end\r\n\r\n trigger :some_trigger_method do\r\n activator.some_behavior # always available\r\n end\r\nend\r\n```\r\n\r\n_Why are those options there?_\r\n\r\nWhen you initialize a context and apply behavior at the same time, you'll need\r\nto remove that behavior. For example, if you are using Casting AND you apply roles on initialize:\r\n\r\n```ruby\r\ncontext = ActiviatingAccount.new(current_user, Account.find(123))\r\ncontext.do_something\r\ncurrent_user.some_behavior # this method is still available\r\ncurrent_user.uncast # you'll have to manually cleanup\r\n```\r\n\r\nBut if you go with the default and apply behaviors on trigger, your roles will be cleaned up automatically:\r\n\r\n```ruby\r\ncontext = ActiviatingAccount.new(current_user, Account.find(123))\r\ncontext.do_something\r\ncurrent_user.some_behavior # NoMethodError\r\n```\r\n\r\n## Overview in code\r\n\r\nHere's a view of the possibilities in code.\r\n\r\n```ruby\r\n# set default role type for *all* contexts in your program\r\nSurrounded::Context.default_role_type = :module # also :wrap, :wrapper, or :interface\r\n\r\nclass ActiviatingAccount\r\n extend Surrounded::Context\r\n\r\n apply_roles_on(:trigger) # this is the default\r\n # apply_roles_on(:initialize) # set this to apply behavior from the start\r\n \r\n set_methods_as_triggers # allows you to skip the 'trigger' dsl\r\n \r\n # set the default role type only for this class\r\n self.default_role_type = :module # also :wrap, :wrapper, or :interface\r\n\r\n initialize(:activator, :account)\r\n\r\n role :activator do # module by default\r\n def some_behavior; end\r\n end\r\n\r\n # role :activator, :module do\r\n # def some_behavior; end\r\n # end\r\n #\r\n # role :activator, :wrap do\r\n # def some_behavior; end\r\n # end\r\n #\r\n # role :activator, :interface do\r\n # def some_behavior; end\r\n # end\r\n #\r\n # use your own classes if you don't want SimpleDelegator\r\n # class SomeSpecialRole\r\n # include Surrounded # you must remember this\r\n # # Surrounded assumes SomeSpecialRole.new(some_special_role)\r\n # def initialize(...);\r\n # # ... your code here\r\n # end\r\n # end\r\n\r\n # works as a trigger (assigning the current context) only if set_methods_as_triggers is set\r\n def regular_method\r\n activator.some_behavior # behavior not available unless you apply roles on initialize\r\n end\r\n\r\n trigger :some_trigger_method do\r\n activator.some_behavior # behavior always available\r\n end\r\nend\r\n```\r\n\r\n## Dependencies\r\n\r\nThe 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.\r\n\r\nIf you're using [Casting](http://github.com/saturnflyer/casting), for example, Surrounded will attempt to use that before extending an object, but it will still work without it.\r\n\r\n## Installation\r\n\r\nAdd this line to your application's Gemfile:\r\n\r\n```ruby\r\ngem 'surrounded'\r\n```\r\n\r\nAnd then execute:\r\n\r\n $ bundle\r\n\r\nOr install it yourself as:\r\n\r\n $ gem install surrounded\r\n \r\n## Installation for Rails\r\n\r\nSee [surrounded-rails](https://github.com/saturnflyer/surrounded-rails)\r\n\r\n## Contributing\r\n\r\n1. Fork it\r\n2. Create your feature branch (`git checkout -b my-new-feature`)\r\n3. Commit your changes (`git commit -am 'Add some feature'`)\r\n4. Push to the branch (`git push origin my-new-feature`)\r\n5. Create new Pull Request\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}
@@ -0,0 +1,226 @@
1
+ html, body, div, span, applet, object, iframe,
2
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
3
+ a, abbr, acronym, address, big, cite, code,
4
+ del, dfn, em, img, ins, kbd, q, s, samp,
5
+ small, strike, strong, sub, sup, tt, var,
6
+ b, u, i, center,
7
+ dl, dt, dd, ol, ul, li,
8
+ fieldset, form, label, legend,
9
+ table, caption, tbody, tfoot, thead, tr, th, td,
10
+ article, aside, canvas, details, embed,
11
+ figure, figcaption, footer, header, hgroup,
12
+ menu, nav, output, ruby, section, summary,
13
+ time, mark, audio, video {
14
+ margin: 0;
15
+ padding: 0;
16
+ border: 0;
17
+ font-size: 100%;
18
+ font: inherit;
19
+ vertical-align: baseline;
20
+ }
21
+ /* HTML5 display-role reset for older browsers */
22
+ article, aside, details, figcaption, figure,
23
+ footer, header, hgroup, menu, nav, section {
24
+ display: block;
25
+ }
26
+ body {
27
+ line-height: 1;
28
+ }
29
+ ol, ul {
30
+ list-style: none;
31
+ }
32
+ blockquote, q {
33
+ quotes: none;
34
+ }
35
+ blockquote:before, blockquote:after,
36
+ q:before, q:after {
37
+ content: '';
38
+ content: none;
39
+ }
40
+ table {
41
+ border-collapse: collapse;
42
+ border-spacing: 0;
43
+ }
44
+ body {
45
+ font-size: 13px;
46
+ line-height: 1.5;
47
+ font-family: 'Helvetica Neue', Helvetica, Arial, serif;
48
+ color: #000;
49
+ }
50
+
51
+ a {
52
+ color: #d5000d;
53
+ font-weight: bold;
54
+ }
55
+
56
+ header {
57
+ padding-top: 35px;
58
+ padding-bottom: 10px;
59
+ }
60
+
61
+ header h1 {
62
+ font-weight: bold;
63
+ letter-spacing: -1px;
64
+ font-size: 48px;
65
+ color: #303030;
66
+ line-height: 1.2;
67
+ }
68
+
69
+ header h2 {
70
+ letter-spacing: -1px;
71
+ font-size: 24px;
72
+ color: #aaa;
73
+ font-weight: normal;
74
+ line-height: 1.3;
75
+ }
76
+ #downloads {
77
+ display: none;
78
+ }
79
+ #main_content {
80
+ padding-top: 20px;
81
+ }
82
+
83
+ code, pre {
84
+ font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal;
85
+ color: #222;
86
+ margin-bottom: 30px;
87
+ font-size: 12px;
88
+ }
89
+
90
+ code {
91
+ padding: 0 3px;
92
+ }
93
+
94
+ pre {
95
+ border: solid 1px #ddd;
96
+ padding: 20px;
97
+ overflow: auto;
98
+ }
99
+ pre code {
100
+ padding: 0;
101
+ }
102
+
103
+ ul, ol, dl {
104
+ margin-bottom: 20px;
105
+ }
106
+
107
+
108
+ /* COMMON STYLES */
109
+
110
+ table {
111
+ width: 100%;
112
+ border: 1px solid #ebebeb;
113
+ }
114
+
115
+ th {
116
+ font-weight: 500;
117
+ }
118
+
119
+ td {
120
+ border: 1px solid #ebebeb;
121
+ text-align: center;
122
+ font-weight: 300;
123
+ }
124
+
125
+ form {
126
+ background: #f2f2f2;
127
+ padding: 20px;
128
+
129
+ }
130
+
131
+
132
+ /* GENERAL ELEMENT TYPE STYLES */
133
+
134
+ h1 {
135
+ font-size: 2.8em;
136
+ }
137
+
138
+ h2 {
139
+ font-size: 22px;
140
+ font-weight: bold;
141
+ color: #303030;
142
+ margin-bottom: 8px;
143
+ }
144
+
145
+ h3 {
146
+ color: #d5000d;
147
+ font-size: 18px;
148
+ font-weight: bold;
149
+ margin-bottom: 8px;
150
+ }
151
+
152
+ h4 {
153
+ font-size: 16px;
154
+ color: #303030;
155
+ font-weight: bold;
156
+ }
157
+
158
+ h5 {
159
+ font-size: 1em;
160
+ color: #303030;
161
+ }
162
+
163
+ h6 {
164
+ font-size: .8em;
165
+ color: #303030;
166
+ }
167
+
168
+ p {
169
+ font-weight: 300;
170
+ margin-bottom: 20px;
171
+ }
172
+
173
+ a {
174
+ text-decoration: none;
175
+ }
176
+
177
+ p a {
178
+ font-weight: 400;
179
+ }
180
+
181
+ blockquote {
182
+ font-size: 1.6em;
183
+ border-left: 10px solid #e9e9e9;
184
+ margin-bottom: 20px;
185
+ padding: 0 0 0 30px;
186
+ }
187
+
188
+ ul li {
189
+ list-style: disc inside;
190
+ padding-left: 20px;
191
+ }
192
+
193
+ ol li {
194
+ list-style: decimal inside;
195
+ padding-left: 3px;
196
+ }
197
+
198
+ dl dd {
199
+ font-style: italic;
200
+ font-weight: 100;
201
+ }
202
+
203
+ footer {
204
+ margin-top: 40px;
205
+ padding-top: 20px;
206
+ padding-bottom: 30px;
207
+ font-size: 13px;
208
+ color: #aaa;
209
+ }
210
+
211
+ footer a {
212
+ color: #666;
213
+ }
214
+
215
+ /* MISC */
216
+ .clearfix:after {
217
+ clear: both;
218
+ content: '.';
219
+ display: block;
220
+ visibility: hidden;
221
+ height: 0;
222
+ }
223
+
224
+ .clearfix {display: inline-block;}
225
+ * html .clearfix {height: 1%;}
226
+ .clearfix {display: block;}
@@ -0,0 +1,69 @@
1
+ .highlight { background: #ffffff; }
2
+ .highlight .c { color: #999988; font-style: italic } /* Comment */
3
+ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
4
+ .highlight .k { font-weight: bold } /* Keyword */
5
+ .highlight .o { font-weight: bold } /* Operator */
6
+ .highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
7
+ .highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
8
+ .highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
9
+ .highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
10
+ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
11
+ .highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
12
+ .highlight .ge { font-style: italic } /* Generic.Emph */
13
+ .highlight .gr { color: #aa0000 } /* Generic.Error */
14
+ .highlight .gh { color: #999999 } /* Generic.Heading */
15
+ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
16
+ .highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
17
+ .highlight .go { color: #888888 } /* Generic.Output */
18
+ .highlight .gp { color: #555555 } /* Generic.Prompt */
19
+ .highlight .gs { font-weight: bold } /* Generic.Strong */
20
+ .highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */
21
+ .highlight .gt { color: #aa0000 } /* Generic.Traceback */
22
+ .highlight .kc { font-weight: bold } /* Keyword.Constant */
23
+ .highlight .kd { font-weight: bold } /* Keyword.Declaration */
24
+ .highlight .kn { font-weight: bold } /* Keyword.Namespace */
25
+ .highlight .kp { font-weight: bold } /* Keyword.Pseudo */
26
+ .highlight .kr { font-weight: bold } /* Keyword.Reserved */
27
+ .highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
28
+ .highlight .m { color: #009999 } /* Literal.Number */
29
+ .highlight .s { color: #d14 } /* Literal.String */
30
+ .highlight .na { color: #008080 } /* Name.Attribute */
31
+ .highlight .nb { color: #0086B3 } /* Name.Builtin */
32
+ .highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
33
+ .highlight .no { color: #008080 } /* Name.Constant */
34
+ .highlight .ni { color: #800080 } /* Name.Entity */
35
+ .highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
36
+ .highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
37
+ .highlight .nn { color: #555555 } /* Name.Namespace */
38
+ .highlight .nt { color: #000080 } /* Name.Tag */
39
+ .highlight .nv { color: #008080 } /* Name.Variable */
40
+ .highlight .ow { font-weight: bold } /* Operator.Word */
41
+ .highlight .w { color: #bbbbbb } /* Text.Whitespace */
42
+ .highlight .mf { color: #009999 } /* Literal.Number.Float */
43
+ .highlight .mh { color: #009999 } /* Literal.Number.Hex */
44
+ .highlight .mi { color: #009999 } /* Literal.Number.Integer */
45
+ .highlight .mo { color: #009999 } /* Literal.Number.Oct */
46
+ .highlight .sb { color: #d14 } /* Literal.String.Backtick */
47
+ .highlight .sc { color: #d14 } /* Literal.String.Char */
48
+ .highlight .sd { color: #d14 } /* Literal.String.Doc */
49
+ .highlight .s2 { color: #d14 } /* Literal.String.Double */
50
+ .highlight .se { color: #d14 } /* Literal.String.Escape */
51
+ .highlight .sh { color: #d14 } /* Literal.String.Heredoc */
52
+ .highlight .si { color: #d14 } /* Literal.String.Interpol */
53
+ .highlight .sx { color: #d14 } /* Literal.String.Other */
54
+ .highlight .sr { color: #009926 } /* Literal.String.Regex */
55
+ .highlight .s1 { color: #d14 } /* Literal.String.Single */
56
+ .highlight .ss { color: #990073 } /* Literal.String.Symbol */
57
+ .highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
58
+ .highlight .vc { color: #008080 } /* Name.Variable.Class */
59
+ .highlight .vg { color: #008080 } /* Name.Variable.Global */
60
+ .highlight .vi { color: #008080 } /* Name.Variable.Instance */
61
+ .highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
62
+
63
+ .type-csharp .highlight .k { color: #0000FF }
64
+ .type-csharp .highlight .kt { color: #0000FF }
65
+ .type-csharp .highlight .nf { color: #000000; font-weight: normal }
66
+ .type-csharp .highlight .nc { color: #2B91AF }
67
+ .type-csharp .highlight .nn { color: #000000 }
68
+ .type-csharp .highlight .s { color: #A31515 }
69
+ .type-csharp .highlight .sc { color: #A31515 }