Froze rails gems
[depot.git] / vendor / rails / activesupport / lib / active_support / vendor / builder-2.1.2 / blankslate.rb
1 #!/usr/bin/env ruby
2 #--
3 # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
4 # All rights reserved.
5
6 # Permission is granted for use, copying, modification, distribution,
7 # and distribution of modified versions of this work as long as the
8 # above copyright notice is included.
9 #++
10
11 ######################################################################
12 # BlankSlate provides an abstract base class with no predefined
13 # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
14 # BlankSlate is useful as a base class when writing classes that
15 # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
16 #
17 class BlankSlate
18 class << self
19
20 # Hide the method named +name+ in the BlankSlate class. Don't
21 # hide +instance_eval+ or any method beginning with "__".
22 def hide(name)
23 if instance_methods.include?(name.to_s) and
24 name !~ /^(__|instance_eval)/
25 @hidden_methods ||= {}
26 @hidden_methods[name.to_sym] = instance_method(name)
27 undef_method name
28 end
29 end
30
31 def find_hidden_method(name)
32 @hidden_methods ||= {}
33 @hidden_methods[name] || superclass.find_hidden_method(name)
34 end
35
36 # Redefine a previously hidden method so that it may be called on a blank
37 # slate object.
38 def reveal(name)
39 bound_method = nil
40 unbound_method = find_hidden_method(name)
41 fail "Don't know how to reveal method '#{name}'" unless unbound_method
42 define_method(name) do |*args|
43 bound_method ||= unbound_method.bind(self)
44 bound_method.call(*args)
45 end
46 end
47 end
48
49 instance_methods.each { |m| hide(m) }
50 end
51
52 ######################################################################
53 # Since Ruby is very dynamic, methods added to the ancestors of
54 # BlankSlate <em>after BlankSlate is defined</em> will show up in the
55 # list of available BlankSlate methods. We handle this by defining a
56 # hook in the Object and Kernel classes that will hide any method
57 # defined after BlankSlate has been loaded.
58 #
59 module Kernel
60 class << self
61 alias_method :blank_slate_method_added, :method_added
62
63 # Detect method additions to Kernel and remove them in the
64 # BlankSlate class.
65 def method_added(name)
66 result = blank_slate_method_added(name)
67 return result if self != Kernel
68 BlankSlate.hide(name)
69 result
70 end
71 end
72 end
73
74 ######################################################################
75 # Same as above, except in Object.
76 #
77 class Object
78 class << self
79 alias_method :blank_slate_method_added, :method_added
80
81 # Detect method additions to Object and remove them in the
82 # BlankSlate class.
83 def method_added(name)
84 result = blank_slate_method_added(name)
85 return result if self != Object
86 BlankSlate.hide(name)
87 result
88 end
89
90 def find_hidden_method(name)
91 nil
92 end
93 end
94 end
95
96 ######################################################################
97 # Also, modules included into Object need to be scanned and have their
98 # instance methods removed from blank slate. In theory, modules
99 # included into Kernel would have to be removed as well, but a
100 # "feature" of Ruby prevents late includes into modules from being
101 # exposed in the first place.
102 #
103 class Module
104 alias blankslate_original_append_features append_features
105 def append_features(mod)
106 result = blankslate_original_append_features(mod)
107 return result if mod != Object
108 instance_methods.each do |name|
109 BlankSlate.hide(name)
110 end
111 result
112 end
113 end