Reputation: 6882
So, I need to make a method within a class protected from re-definition. I am not really sure how else to explain it so here's the code:
module Foo
def bar
p "lol"
end
end
Now, that's the original Foo#bar
method and I need it to be like a constant. So, I did come up with a solution. That was to save the method in a Constant and detect when someone tried changing it it would simply re-load it from that constant (it was a Proc object):
module Foo
Original_bar = Proc.new { p "lol" }
def bar
Original_bar.call
end
def self.method_added(method_name)
if method_name == :bar
def Foo::bar
Original_bar.call
end
end
end
end
But this isn't completely safe since once could use the same "trick" I did to bypass method_added
and I am not really fond of this, since it's not very ruby-like.
A normal test:
module Foo
def bar
p "lmao"
end
end
Foo::bar # => "lol"
And another test using the trick:
def Foo::bar
p "rofl"
end
Foo::bar # => "rofl"
How to make a method in Ruby "unredefinable" (if that's even a word)?
Upvotes: 1
Views: 414
Reputation: 81510
You can make your code warn you that a method has been over-ridden by turning on warnings:
$VERBOSE = true
module Foo
def self.bar
p "lmao"
end
end
def Foo::bar
p "rofl"
end
(irb):9: warning: method redefined; discarding old bar
It may be possible, but not practical, to raise an exception when warnings are issued.
This won't warn you if you first undefine Foo.bar, however.
Upvotes: 0
Reputation: 84114
If you freeze the module that should prevent method being added to it.
Note that a c extension can unfreeze variables (see evil.rb for example.
Upvotes: 1