I am quite new to Ruby, so still learning. I was researching quite a bit about how to add methods dynamically, and I was successful to create instance methods, but not successful when creating class methods.
This is how I generated instance methods:
class B
def before_method
puts "before method"
end
def self.run(method)
send :define_method, method do
before_method
puts "method #{method}"
end
end
end
class A < B
run :m
run :n
end
Any idea about the best ways to create static methods?
My final task is to look for the best way to create "before" and "after" tasks for class methods.
define_method is a method defined in Module class which you can use to create methods dynamically. To use define_method , you call it with the name of the new method and a block where the parameters of the block become the parameters of the new method.
Class methods are called on the class itself (hence why in the method declaration, it will always state def self. class_method_name ), whereas instance methods are called on a particular instance of the class (these are declared like regular methods: def instance_method_name ). As you can see, when Example.
In Ruby, a method provides functionality to an Object. A class method provides functionality to a class itself, while an instance method provides functionality to one instance of a class. We cannot call an instance method on the class itself, and we cannot directly call a class method on an instance.
Metaprogramming is a technique in which code operates on code rather than on data. It can be used to write programs that write code dynamically at run time. MetaProgramming gives Ruby the ability to open and modify classes, create methods on the fly and much more.
To create instance methods dynamically, try
class Foo
LIST = %w(a b c)
LIST.each do |x|
define_method(x) do |arg|
return arg+5
end
end
end
Now any instance of Foo would have the method "a", "b", "c". Try
Foo.new.a(10)
To define class methods dynamically, try
class Foo
LIST = %w(a b c)
class << self
LIST.each do |x|
define_method(x) do |arg|
return arg+5
end
end
end
end
Then try
Foo.a(10)
Instance methods of an objects singleton class are singleton methods of the object itself. So if you do
class B
def self.run(method)
singleton_class = class << self; self; end
singleton_class.send(:define_method, method) do
puts "Method #{method}"
end
end
end
you can now call
B.run :foo
B.foo
=> Method foo
(Edit: added B.run :foo as per Lars Haugseth's comment)
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