docile 0.9.0 → 0.9.1
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.
- data/README.md +12 -5
- data/lib/docile/version.rb +1 -1
- data/spec/docile_spec.rb +30 -9
- metadata +1 -1
data/README.md
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
Definition: *Ready to accept control or instruction; submissive* [[1]]
|
4
4
|
|
5
5
|
Tired of overly complex DSL libraries and hairy meta-programming?
|
6
|
-
|
6
|
+
|
7
|
+
Let's make our Ruby DSLs more docile...
|
7
8
|
|
8
9
|
[1]: http://www.google.com/search?q=docile+definition "Google"
|
9
10
|
|
@@ -15,31 +16,36 @@ Let's treat an Array's methods as its own DSL:
|
|
15
16
|
Docile.dsl_eval [] do
|
16
17
|
push 1
|
17
18
|
push 2
|
19
|
+
pop
|
20
|
+
push 3
|
18
21
|
end
|
19
22
|
#=> [1, 3]
|
20
23
|
```
|
21
24
|
|
22
25
|
Mutating (changing) the array is fine, but what you probably really want as your DSL is actually a [Builder Pattern][2].
|
23
26
|
|
24
|
-
For example, if you have a PizzaBuilder class that can build a
|
27
|
+
For example, if you have a PizzaBuilder class that can already build a Pizza:
|
25
28
|
|
26
29
|
``` ruby
|
27
30
|
@sauce_level = :extra
|
28
|
-
pizza = PizzaBuilder.new.cheese.pepperoni.
|
31
|
+
pizza = PizzaBuilder.new.cheese.pepperoni.sauce(@sauce_level).build
|
32
|
+
#=> #<Pizza:0x00001009dc398 @cheese=true, @pepperoni=true, @bacon=false, @sauce=:extra>
|
29
33
|
```
|
30
34
|
|
31
|
-
Then you can use this PizzaBuilder class as a DSL:
|
35
|
+
Then you can use this same PizzaBuilder class as a DSL:
|
32
36
|
|
33
37
|
``` ruby
|
34
38
|
@sauce_level = :extra
|
35
39
|
pizza = Docile.dsl_eval PizzaBuilder.new do
|
36
40
|
cheese
|
37
41
|
pepperoni
|
38
|
-
bacon
|
39
42
|
sauce @sauce_level
|
40
43
|
end.build
|
44
|
+
#=> #<Pizza:0x00001009dc398 @cheese=true, @pepperoni=true, @bacon=false, @sauce=:extra>
|
41
45
|
```
|
42
46
|
|
47
|
+
It's just that easy!
|
48
|
+
|
43
49
|
[2]: http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern "Builder Pattern"
|
44
50
|
|
45
51
|
## Features
|
@@ -47,6 +53,7 @@ end.build
|
|
47
53
|
1. method lookup falls back from the DSL object to the block's context
|
48
54
|
2. local variable lookup falls back from the DSL object to the block's context
|
49
55
|
3. instance variables are from the block's context only
|
56
|
+
4. nested dsl evaluation
|
50
57
|
|
51
58
|
## Installation
|
52
59
|
|
data/lib/docile/version.rb
CHANGED
data/spec/docile_spec.rb
CHANGED
@@ -4,6 +4,36 @@ describe Docile do
|
|
4
4
|
|
5
5
|
context :dsl_eval do
|
6
6
|
|
7
|
+
it "should return the DSL object" do
|
8
|
+
Docile.dsl_eval([]) do
|
9
|
+
push 1
|
10
|
+
push 2
|
11
|
+
pop
|
12
|
+
push 3
|
13
|
+
end.should == [1, 3]
|
14
|
+
end
|
15
|
+
|
16
|
+
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
|
17
|
+
|
18
|
+
class PizzaBuilder
|
19
|
+
def cheese(v=true); @cheese = v; end
|
20
|
+
def pepperoni(v=true); @pepperoni = v; end
|
21
|
+
def bacon(v=true); @bacon = v; end
|
22
|
+
def sauce(v=nil); @sauce = v; end
|
23
|
+
def build
|
24
|
+
Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should handle a Builder pattern" do
|
29
|
+
@sauce = :extra
|
30
|
+
Docile.dsl_eval(PizzaBuilder.new) do
|
31
|
+
bacon
|
32
|
+
cheese
|
33
|
+
sauce @sauce
|
34
|
+
end.build.should == Pizza.new(true, false, true, :extra)
|
35
|
+
end
|
36
|
+
|
7
37
|
class InnerDSL
|
8
38
|
def initialize; @b = 'b'; end
|
9
39
|
attr_accessor :b
|
@@ -21,15 +51,6 @@ describe Docile do
|
|
21
51
|
Docile.dsl_eval(OuterDSL.new, &block)
|
22
52
|
end
|
23
53
|
|
24
|
-
it "should return the DSL object" do
|
25
|
-
Docile.dsl_eval([]) do
|
26
|
-
push 1
|
27
|
-
push 2
|
28
|
-
pop
|
29
|
-
push 3
|
30
|
-
end.should == [1, 3]
|
31
|
-
end
|
32
|
-
|
33
54
|
context "methods" do
|
34
55
|
it "should find method of outer dsl in outer dsl scope" do
|
35
56
|
outer { a.should == 'a' }
|