3 # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
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.
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).
20 # Hide the method named +name+ in the BlankSlate class. Don't
21 # hide +instance_eval+ or any method beginning with "__".
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)
31 def find_hidden_method(name)
32 @hidden_methods ||= {}
33 @hidden_methods[name] || superclass.find_hidden_method(name)
36 # Redefine a previously hidden method so that it may be called on a blank
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)
49 instance_methods.each { |m| hide(m) }
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.
61 alias_method :blank_slate_method_added, :method_added
63 # Detect method additions to Kernel and remove them in the
65 def method_added(name)
66 result = blank_slate_method_added(name)
67 return result if self != Kernel
74 ######################################################################
75 # Same as above, except in Object.
79 alias_method :blank_slate_method_added, :method_added
81 # Detect method additions to Object and remove them in the
83 def method_added(name)
84 result = blank_slate_method_added(name)
85 return result if self != Object
90 def find_hidden_method(name)
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.
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)