bruce (owner)

Revisions

gist: 44230 Download_button fork
public
Public Clone URL: git://gist.github.com/44230.git
Embed All Files: show embed
output.txt #
1
2
3
4
5
6
7
8
Widget metaclass ancestors...
[Wrapper, Class, Module, Object, Kernel]
The 2 `new' methods get invoked...
Invoked Widget::new
Invoked Wrapper's new
The 2 `render_on' methods get invoked...
Invoked Wrapping's render_on
Invoked Widget#render_on
respect-new.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# An example to illiustrate that the super-and-extend method wrapping
# technique respects `new' methods defined on the wrapped class, provided
# that `super' is called.
#
# For information on the super-and-extend technique, see:
# http://codefluency.com/articles/2009/01/03/wrapping-a-method-in-ruby/
 
# This is the class to wrap
class Widget
 
  # Example of a scenario where the target class' `new' method is defined,
  # and `super' is being used, to show invocation order.
  #
  # We don't really care about the *order* that the Wrapper's new (just
  # a hook to extend the instance) fires, the wrapper works as expected.
  #
  # Keep in mind overriding `new' is a fairly rare case.
  #
  def self.new
    puts "Invoked Widget::new"
    super
  end
 
  # The method we're targeting
  def render_on(document, options = {})
    puts "Invoked Widget#render_on"
  end
 
end
 
# Yeah, the name says it
module Wrapper
  
  # `super' here invokes Class#new
  def new
    puts "Invoked Wrapper's new"
    super.extend(Wrapping)
  end
 
  module Wrapping
    
    def render_on(document, options = {})
      puts "Invoked Wrapping's render_on"
      super # Widget#render_on
    end
    
  end
 
end
 
Widget.extend(Wrapper)
 
puts "Widget metaclass ancestors..."
p (class << Widget; self; end).ancestors
 
puts "The 2 `new' methods get invoked..."
widget = Widget.new
 
puts "The 2 `render_on' methods get invoked..."
widget.render_on(nil)