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
)