Reputation: 61
While playing a bit with Ruby, I wrote the following code:
class A
end
A.singleton_class.instance_eval do
undef_method :new
end
# or
# class << B
# undef_method :new
# end
A.new
> NoMethodError: undefined method `new' for A:Class
> from (irb):8
> from /home/mmsequeira/.rvm/rubies/ruby-1.9.3-p327/bin/irb:16:in `<main>'
This is cool. But how can I know which methods have been undefined in a given class?
Upvotes: 2
Views: 347
Reputation: 97024
You can't by default. Undefining a method removes it from existence. You could, however, record them as they're removed. This can be done with method hooks to capture everything and avoid ugly alias method chaining:
class Module
def method_undefined name
(@undefined_methods ||= []) << name
end
def singleton_method_undefined name
(@undefined_methods ||= []) << name
end
def undefined_methods
@undefined_methods || []
end
end
This will capture methods undefined via undef_method
or undef
:
class C
def foo; end
def bar; end
undef foo
undef_method :bar
end
C.undefined_methods #=> [:foo, :bar]
C.singleton_class.instance_eval { undef new }
C.singleton_class.undefined_methods #=> [:new]
Of course, you must include the hook methods in Module before anything can be captured.
Upvotes: 3
Reputation: 168269
Maybe you need to redefine Module#undef_method
.
class Module
alias original_undef_method :undef_method
@@undef_methods = {}
def undef_method *methods
methods.each{|method| @@undef_methods[[self, method]] ||= true}
original_undef_method(*methods)
end
def self.undef_methods; @@undef_methods.keys end
end
Then, you get:
class A
end
A.singleton_class.instance_eval do
undef_method :new
end
Module.undef_methods
# => [[#<Class:A>, :new]]
Upvotes: 1