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 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 in just one
6
- method, and it relies exclusively on Ruby Procs.
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
- def decorator(*options)
15
- lambda { |*args, &blk|
16
- blk.call(*args.map{ |arg| "MAR #{arg}!" })
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 + ' --from foo, with love'
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
 
@@ -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
- here = lambda{ |*decorator_args, &blk|
26
- self.send(new_name, *decorator_args, &blk)
25
+ original = lambda{ |*decorator_args, &inner_block|
26
+ self.send(new_name, *decorator_args, &inner_block)
27
27
  }
28
- decorator.call(*args, &here)
28
+ decorator.call(original, *args, &outer_block)
29
29
  }
30
30
  end
31
31
  end
@@ -1,3 +1,3 @@
1
1
  module Mar
2
- Version = '0.2'
2
+ Version = '1.0.1'
3
3
  end
@@ -1,20 +1,30 @@
1
1
  require 'mar'
2
2
 
3
- def decorator(*options)
4
- lambda { |*args, &blk|
5
- blk.call(*args.map{ |arg| "MAR #{arg}!" })
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 + ' --from foo, with love'
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mar
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: