docile 1.0.4 → 1.0.5

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: 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