Class (re)definition in method body
UPDATE: modifed to use more idiomatic way of returning "***". See comments
Warning: This is really hacky and dirty. Writing the snippet here so I won't forget
Redefining existing classes in Ruby is really handy, and a breeze to do
puts 5 # prints "5"
class Fixnum
alias_method :old_to_s, :to_s
def to_s
"*" * self
end
end
puts 5 # prints "*****"
But, sometimes you'd just want to limit such monkey patching, like within a method where you really really need the hack in place - and you promise to undo the hack right after you're done to return the world sanity (promise!)
class MyKlass
def get_as_stars(value)
# define funky behavior
class ::Fixnum
alias_method :old_to_s, :to_s
def to_s
"*" * self
end
end
return value.to_s
ensure
# revert back to original
class ::Fixnum
alias_method :to_s, :old_to_s
end
end
end
Unfortunately, that's invalid syntax
SyntaxError: compile error
: class definition in method body
: class definition in method body
Well, what's a man to do? module_eval to the rescue, just replace your "class X" statement with "X.module_eval do"
class MyKlass
def get_as_stars(value)
# define funky behavior
::Fixnum.module_eval do
alias_method :old_to_s, :to_s
def to_s
"*" * self
end
end
return value.to_s
ensure
# revert back to original
::Fixnum.module_eval do
alias_method :to_s, :old_to_s
end
end
end
k = MyKlass.new
puts 3 # prints "3"
puts k.get_as_stars(4) # prints "****"
puts 5 # prints "5"
PS: Did this hack to get Time.now == Time.now working in a test. Grr