mar 0.2 → 1.0.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 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: