Code
First create a module containing a single module method, setup
. This module could be put in a file that is required as needed. This module method will be invoked from a module containing instance methods to be included in a given class. Using aliases, it modifies those instance methods to print a message (containing the method name) before executing the remainder of its code.
Module AddMessage
module AddMessage
def self.setup(mod, msg_pre, msg_post)
mod.instance_methods(false).
each do |m|
am = "_#{m}".to_sym
mod.send(:alias_method, am, m)
mod.send(:private, am)
mod.send(:define_method, m) do |*args, &block|
puts "%s %s %s" % [msg_pre, m, msg_post]
send(am, *args, &block)
end
end
end
end
Module to be included in class
module LegacyStuff
def old1
"hi"
end
def old2(a, b)
yield(a, b)
end
AddMessage.setup(self, "Warning:", "is deprecated")
end
AddMessage::setup
is passed three arguments, the name of the calling module and a message prefix and message suffix that are used to form the warning message. When an instance method m
in this module is executed by a class instance the message "Warning: #{m} is deprecated"
is printed (e.g., "Warning: old1 is deprecated"
) before the remaining calculations are performed.
Use
LegacyStuff
is simply included by a class.
class C
include LegacyStuff
# <constants, methods and so forth go here>
end
c = C.new
c.old1
# Warning: old1 is deprecated
#=> "hi"
c.old2(1,2) { |a,b| a+b }
# Warning: old2 is deprecated
#=> 3
c.cat
#=> NoMethodError: undefined method `cat' for #<C:0x000000008ef0a8>
Explanation of the module method AddMessage:setup
The following (of the generally less-familiar) methods are used by this method: Module#instance_methods, Module#alias_method, Module#private and Module#define_method.
The following three steps are performed for each instance method m
defined in module mod
(e.g., elements of the array LegacyStuff.instance_methods(false)
).
mod.send(:alias_method, am, m)
Create an alias am
of the method (e.g., _:old1
for old1
).
mod.send(:private, am)
Make the alias am
a private method (e.g., _old1
).
mod.send(:define_method, m) do |*args, &block| ... end
Redefine the method m
(e.g., old1
) to print the indicate string and then execute the alias am
(e.g., _old1
).