docile 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b295f680ae1c64b5825a284bea4efbd8ddaa2c5b
4
- data.tar.gz: d4f19b3d37e262cdbe117c98d40695798c8bfb94
3
+ metadata.gz: 75054a395059cd55ba3132c00dc49ae15cc6b954
4
+ data.tar.gz: 71f6114e6ac5d727240bd50c8e967127af688a53
5
5
  SHA512:
6
- metadata.gz: 88e3011f1060083fac18a51a6337fc0f6f8f85f6c87ff45a596a8da35164374a5d815a47d20b76bee791bc346874b77062b702f90bbb81e6a5058049503cbf5a
7
- data.tar.gz: 6d53a3345ce3f6ed0612cc445bdc338e8f6c3e8e53e405aedf70cfc106c9c56c02377bad6d331147b48e910f8936bcd510846bf1c6ad17a4c8e14f954905662b
6
+ metadata.gz: 57476b49adfb0e49f909c391420f6c7b1fdacd2fcf5aaced53443bd3c138ca6ca70ba047b261c9c20dc899a1a35e70950d3582f0dc267d33a2d5748dfd53aee1
7
+ data.tar.gz: 46b4708db7b9cb68b3f1415edb0f07d5dcc49ba6d86831a51b96e1774abcea346aa3f7412e106572d32893f2473ff7ccddae0596470efad85a1c08a1d737b91c
data/HISTORY.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # HISTORY
2
2
 
3
+ ## [v1.0.5 (Jul 28, 2013)](http://github.com/ms-ati/docile/compare/v1.0.4...v1.0.5)
4
+
5
+ - achieve 100% yard docs coverage
6
+ - fix rendering of docs at http://rubydoc.info/gems/docile
7
+
3
8
  ## [v1.0.4 (Jul 25, 2013)](http://github.com/ms-ati/docile/compare/v1.0.3...v1.0.4)
4
9
 
5
10
  - simplify and clarify code
data/README.md CHANGED
@@ -30,6 +30,7 @@ end
30
30
  ```
31
31
 
32
32
  No problem, just define the method `with_array` like this:
33
+
33
34
  ``` ruby
34
35
  def with_array(arr=[], &block)
35
36
  Docile.dsl_eval(arr, &block)
@@ -43,6 +44,7 @@ Easy!
43
44
  Mutating (changing) an Array instance is fine, but what usually makes a good DSL is a [Builder Pattern][2].
44
45
 
45
46
  For example, let's say you want a DSL to specify how you want to build a Pizza:
47
+
46
48
  ```ruby
47
49
  @sauce_level = :extra
48
50
 
@@ -55,6 +57,7 @@ end
55
57
  ```
56
58
 
57
59
  And let's say we have a PizzaBuilder, which builds a Pizza like this:
60
+
58
61
  ```ruby
59
62
  Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
60
63
 
@@ -89,6 +92,7 @@ It's just that easy!
89
92
  Parameters can be passed to the DSL block.
90
93
 
91
94
  Supposing you want to make some sort of cheap [Sinatra][3] knockoff:
95
+
92
96
  ```ruby
93
97
  @last_request = nil
94
98
  respond '/path' do |request|
@@ -106,6 +110,7 @@ end
106
110
  ```
107
111
 
108
112
  You'd put together a dispatcher something like this:
113
+
109
114
  ```ruby
110
115
  require 'singleton'
111
116
 
data/Rakefile CHANGED
@@ -1,7 +1,17 @@
1
+ require "rake/clean"
1
2
  require "bundler/gem_tasks"
2
3
  require "rspec/core/rake_task"
3
4
 
4
- # Don't require doc generation gems on Travis
5
+ # Default task for `rake` is to run rspec
6
+ task :default => [:spec]
7
+
8
+ # Use default rspec rake task
9
+ RSpec::Core::RakeTask.new
10
+
11
+ # Configure `rake clobber` to delete all generated files
12
+ CLOBBER.include("pkg", "doc", "coverage")
13
+
14
+ # Only configure yard doc generation when *not* on Travis
5
15
  if ENV['CI'] != 'true'
6
16
  require "github/markup"
7
17
  require "redcarpet"
@@ -14,7 +24,3 @@ if ENV['CI'] != 'true'
14
24
  t.options = %w(--markup-provider=redcarpet --markup=markdown --main=README.md)
15
25
  end
16
26
  end
17
-
18
- RSpec::Core::RakeTask.new
19
-
20
- task :default => [:spec]
data/lib/docile.rb CHANGED
@@ -1,34 +1,53 @@
1
1
  require "docile/version"
2
2
  require "docile/fallback_context_proxy"
3
3
 
4
+ # Docile keeps your Ruby DSLs tame and well-behaved
5
+ # @see http://ms-ati.github.com/docile/
4
6
  module Docile
5
- # Executes a block in the context of an object whose interface represents a DSL.
7
+ # Execute a block in the context of an object whose methods represent the
8
+ # commands in a DSL.
6
9
  #
7
- # Example of using an Array as a DSL:
10
+ # @note Use with an *imperative* DSL (commands modify the context object)
8
11
  #
9
- # Docile.dsl_eval [] do
10
- # push 1
11
- # push 2
12
- # pop
13
- # push 3
14
- # end
15
- # #=> [1, 3]
12
+ # Use this method to execute an *imperative* DSL, which means that:
16
13
  #
17
- # @param dsl [Object] an object whose methods represent a DSL
14
+ # 1. each command mutates the state of the DSL context object
15
+ # 2. the return values of the commands are ignored
16
+ #
17
+ # @example Use a String as a DSL
18
+ # Docile.dsl_eval("Hello, world!") do
19
+ # reverse!
20
+ # upcase!
21
+ # end
22
+ # #=> "!DLROW ,OLLEH"
23
+ #
24
+ # @example Use an Array as a DSL
25
+ # Docile.dsl_eval([]) do
26
+ # push 1
27
+ # push 2
28
+ # pop
29
+ # push 3
30
+ # end
31
+ # #=> [1, 3]
32
+ #
33
+ # @param dsl [Object] context object whose methods make up the DSL
18
34
  # @param args [Array] arguments to be passed to the block
19
- # @param block [Proc] a block to execute in the DSL context
20
- # @return [Object] the dsl object, after execution of the block
35
+ # @yield the block of DSL commands to be executed against the
36
+ # `dsl` context object
37
+ # @return [Object] the `dsl` context object after executing the block
21
38
  def dsl_eval(dsl, *args, &block)
22
39
  block_context = eval("self", block.binding)
23
40
  proxy_context = FallbackContextProxy.new(dsl, block_context)
24
41
  begin
25
42
  block_context.instance_variables.each do |ivar|
26
- proxy_context.instance_variable_set(ivar, block_context.instance_variable_get(ivar))
43
+ value_from_block = block_context.instance_variable_get(ivar)
44
+ proxy_context.instance_variable_set(ivar, value_from_block)
27
45
  end
28
- proxy_context.instance_exec(*args,&block)
46
+ proxy_context.instance_exec(*args, &block)
29
47
  ensure
30
48
  block_context.instance_variables.each do |ivar|
31
- block_context.instance_variable_set(ivar, proxy_context.instance_variable_get(ivar))
49
+ value_from_dsl_proxy = proxy_context.instance_variable_get(ivar)
50
+ block_context.instance_variable_set(ivar, value_from_dsl_proxy)
32
51
  end
33
52
  end
34
53
  dsl
@@ -1,28 +1,51 @@
1
1
  require 'set'
2
2
 
3
3
  module Docile
4
+ # A proxy object with a primary receiver as well as a secondary
5
+ # fallback receiver.
6
+ #
7
+ # Will attempt to forward all method calls first to the primary receiver,
8
+ # and then to the fallback receiver if the primary does not handle that
9
+ # method.
4
10
  class FallbackContextProxy
11
+ # The set of methods which will **not** be proxied, but instead answered
12
+ # by this object directly.
5
13
  NON_PROXIED_METHODS = Set[:__send__, :object_id, :__id__, :==, :equal?,
6
14
  :"!", :"!=", :instance_exec, :instance_variables,
7
15
  :instance_variable_get, :instance_variable_set,
8
16
  :remove_instance_variable]
9
17
 
18
+ # The set of instance variables which are local to this object and hidden.
19
+ # All other instance variables will be copied in and out of this object
20
+ # from the scope in which this proxy was created.
10
21
  NON_PROXIED_INSTANCE_VARIABLES = Set[:@__receiver__, :@__fallback__]
11
22
 
23
+ # Undefine all instance methods except those in {NON_PROXIED_METHODS}
12
24
  instance_methods.each do |method|
13
25
  undef_method(method) unless NON_PROXIED_METHODS.include?(method.to_sym)
14
26
  end
15
27
 
28
+ # @param [Object] receiver the primary proxy target to which all methods
29
+ # initially will be forwarded
30
+ # @param [Object] fallback the fallback proxy target to which any methods
31
+ # not handled by `receiver` will be forwarded
16
32
  def initialize(receiver, fallback)
17
33
  @__receiver__ = receiver
18
34
  @__fallback__ = fallback
19
35
  end
20
36
 
37
+ # @return [Array<Symbol>] Instance variable names, excluding
38
+ # {NON_PROXIED_INSTANCE_VARIABLES}
39
+ #
40
+ # @note on Ruby 1.8.x, the instance variable names are actually of
41
+ # type `String`.
21
42
  def instance_variables
22
43
  # Ruby 1.8.x returns string names, convert to symbols for compatibility
23
44
  super.select { |v| !NON_PROXIED_INSTANCE_VARIABLES.include?(v.to_sym) }
24
45
  end
25
46
 
47
+ # Proxy all methods, excluding {NON_PROXIED_METHODS}, first to `receiver`
48
+ # and then to `fallback` if not found.
26
49
  def method_missing(method, *args, &block)
27
50
  @__receiver__.__send__(method.to_sym, *args, &block)
28
51
  rescue ::NoMethodError => e
@@ -1,3 +1,4 @@
1
1
  module Docile
2
- VERSION = "1.0.4"
2
+ # The current version of this library
3
+ VERSION = "1.0.5"
3
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docile
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Siegel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-25 00:00:00.000000000 Z
11
+ date: 2013-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake