I'm writing a module in Ruby 1.9.2 that defines several methods. When any of these methods is called, I want each of them to execute a certain statement first.
module MyModule def go_forth a re-used statement # code particular to this method follows ... end def and_multiply a re-used statement # then something completely different ... end end
But I want to avoid putting that a re-used statement
code explicitly in every single method. Is there a way to do so?
(If it matters, a re-used statement
will have each method, when called, print its own name. It will do so via some variant of puts __method__
.)
As with class methods, you call a module method by preceding its name with the module's name and a period, and you reference a constant using the module name and two colons.
In ruby, the concept of object orientation takes its roots from Smalltalk. Basically, when you call a method, you are sending that object a message. So, it makes sense that when you want to dynamically call a method on an object, the method you call is send . This method has existed in ruby since at least 1.8.
A user cannot access instance method directly with the use of the dot operator as he cannot make the instance of the module. To access the instance method defined inside the module, the user has to include the module inside a class and then use the class instance to access that method.
Like this:
module M def self.before(*names) names.each do |name| m = instance_method(name) define_method(name) do |*args, &block| yield m.bind(self).(*args, &block) end end end end module M def hello puts "yo" end def bye puts "bum" end before(*instance_methods) { puts "start" } end class C include M end C.new.bye #=> "start" "bum" C.new.hello #=> "start" "yo"
This is exactly what aspector is created for.
With aspector you don't need to write the boilerplate metaprogramming code. You can even go one step further to extract the common logic into a separate aspect class and test it independently.
require 'aspector' module MyModule aspector do before :go_forth, :add_multiply do ... end end def go_forth # code particular to this method follows ... end def and_multiply # then something completely different ... end end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With