mar 0.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +28 -9
- data/lib/mar/mar.rb +4 -4
- data/lib/mar/version.rb +1 -1
- data/spec/test_mar.rb +26 -7
- metadata +1 -1
data/README.md
CHANGED
@@ -2,8 +2,8 @@ MAR
|
|
2
2
|
===
|
3
3
|
|
4
4
|
Inspired by [this blog post][ruby-decorators], I started looking into what it
|
5
|
-
might actually take to implement it. Turns out, it can be done
|
6
|
-
|
5
|
+
might actually take to implement it. Turns out, it can be done with just a few
|
6
|
+
methods tacked onto `Class`. It relies exclusively on Ruby Procs.
|
7
7
|
|
8
8
|
Examble
|
9
9
|
=======
|
@@ -11,21 +11,31 @@ Examble
|
|
11
11
|
```ruby
|
12
12
|
require 'mar'
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
# a decorator function *returns* a lambda. methods aren't first-class in Ruby,
|
15
|
+
# so this is just how it's got to be. On the other hand, it makes it very easy
|
16
|
+
# to accept options and use those in the method decorator!
|
17
|
+
def decorator(name)
|
18
|
+
lambda { |original, arg, &blk|
|
19
|
+
original.call("MAR #{arg}! --from #{name}", &blk)
|
17
20
|
}
|
18
21
|
end
|
19
22
|
|
20
23
|
class Foo
|
21
|
-
_ decorator('foo')
|
22
|
-
def foo(one_arg)
|
23
|
-
one_arg + '
|
24
|
+
_ decorator('foo') # this gets passed in as an "option" to decorator()
|
25
|
+
def foo(one_arg) # this get called via blk.call, which manipulates one_arg before calling the original method
|
26
|
+
one_arg + ', with love'
|
24
27
|
end
|
25
28
|
|
26
|
-
def bar
|
29
|
+
def bar # this doesn't get changed at all, but let's make sure of that...
|
27
30
|
'I get no respect, I tell ya\', no respect.'
|
28
31
|
end
|
32
|
+
|
33
|
+
_ decorator('baz') # this time, let's accept a block!
|
34
|
+
def baz(one_arg)
|
35
|
+
yield
|
36
|
+
one_arg
|
37
|
+
end
|
38
|
+
|
29
39
|
end
|
30
40
|
|
31
41
|
describe "Mar" do
|
@@ -40,6 +50,15 @@ describe "Mar" do
|
|
40
50
|
it 'should NOT decorate Foo#bar' do
|
41
51
|
@foo.bar.should == 'I get no respect, I tell ya\', no respect.'
|
42
52
|
end
|
53
|
+
|
54
|
+
it 'should decorate Foo#baz and accept a block' do
|
55
|
+
two = 1
|
56
|
+
nifty = @foo.baz('is nifty') {
|
57
|
+
two = 2
|
58
|
+
}
|
59
|
+
nifty.should == 'MAR is nifty! --from baz'
|
60
|
+
two.should == 2
|
61
|
+
end
|
43
62
|
end
|
44
63
|
```
|
45
64
|
|
data/lib/mar/mar.rb
CHANGED
@@ -20,12 +20,12 @@ class Class
|
|
20
20
|
if decorators.length > 0
|
21
21
|
new_name = "marrrrrrrr_#{name}"
|
22
22
|
alias_method new_name, name
|
23
|
-
define_method(name) { |*args|
|
23
|
+
define_method(name) { |*args, &outer_block|
|
24
24
|
decorator = decorators[0]
|
25
|
-
|
26
|
-
self.send(new_name, *decorator_args, &
|
25
|
+
original = lambda{ |*decorator_args, &inner_block|
|
26
|
+
self.send(new_name, *decorator_args, &inner_block)
|
27
27
|
}
|
28
|
-
decorator.call(*args, &
|
28
|
+
decorator.call(original, *args, &outer_block)
|
29
29
|
}
|
30
30
|
end
|
31
31
|
end
|
data/lib/mar/version.rb
CHANGED
data/spec/test_mar.rb
CHANGED
@@ -1,20 +1,30 @@
|
|
1
1
|
require 'mar'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
# a decorator function *returns* a lambda. methods aren't first-class in Ruby,
|
4
|
+
# so this is just how it's got to be. On the other hand, it makes it very easy
|
5
|
+
# to accept options and use those in the method decorator!
|
6
|
+
def decorator(name)
|
7
|
+
lambda { |original, arg, &blk|
|
8
|
+
original.call("MAR #{arg}! --from #{name}", &blk)
|
6
9
|
}
|
7
10
|
end
|
8
11
|
|
9
12
|
class Foo
|
10
|
-
_ decorator('foo')
|
11
|
-
def foo(one_arg)
|
12
|
-
one_arg + '
|
13
|
+
_ decorator('foo') # this gets passed in as an "option" to decorator()
|
14
|
+
def foo(one_arg) # this get called via blk.call, which manipulates one_arg before calling the original method
|
15
|
+
one_arg + ', with love'
|
13
16
|
end
|
14
17
|
|
15
|
-
def bar
|
18
|
+
def bar # this doesn't get changed at all, but let's make sure of that...
|
16
19
|
'I get no respect, I tell ya\', no respect.'
|
17
20
|
end
|
21
|
+
|
22
|
+
_ decorator('baz') # this time, let's accept a block!
|
23
|
+
def baz(one_arg)
|
24
|
+
yield
|
25
|
+
one_arg
|
26
|
+
end
|
27
|
+
|
18
28
|
end
|
19
29
|
|
20
30
|
describe "Mar" do
|
@@ -29,4 +39,13 @@ describe "Mar" do
|
|
29
39
|
it 'should NOT decorate Foo#bar' do
|
30
40
|
@foo.bar.should == 'I get no respect, I tell ya\', no respect.'
|
31
41
|
end
|
42
|
+
|
43
|
+
it 'should decorate Foo#baz and accept a block' do
|
44
|
+
two = 1
|
45
|
+
nifty = @foo.baz('is nifty') {
|
46
|
+
two = 2
|
47
|
+
}
|
48
|
+
nifty.should == 'MAR is nifty! --from baz'
|
49
|
+
two.should == 2
|
50
|
+
end
|
32
51
|
end
|