class MinhaClasse
def metodo
# meu método
end
end
What is happening here is quite simple: You are creating an instance method in the MinhaClasse
class. Nothing unusual.
class MinhaClasse
outro_metodo
end
Already when you write this, you are calling the outro_metodo
method on the self
object of the context. In this case, the self
within the scope of the class is the class itself. This is equivalent to doing MinhaClasse.outro_metodo
.
This method could have been defined like this:
def MinhaClasse.outro_metodo
# código
end
Or so, equivalently:
class MinhaClasse
def self.outro_metodo
# código
end
end
Of course, like any other method invocation, you can pass a block, and the implementation can do whatever you want with the block, including defining an instance method using the block passed as the implementation of it. Something like this:
class MinhaClasse
def self.criar_metodo(&bloco)
define_method(:metodo, &bloco)
end
criar_metodo do
puts "oi!"
end
end
obj = MinhaClasse.new
obj.metodo #=> "oi!"
Here I used define_method
, which is a method of class Class
to define methods from a block. One can even argue that def metodo(a, b) ... end
is a mere syntactic sugar for define_method(:metodo) do |a, b| ... end
.
As for use, metaprogramming! This allows you to create syntaxes with "special" behavior, and make the language behave as you want. For example:
class MyButton < Button
on :click do
puts "Me clicou!"
end
end
That could be implemented as:
def Button.on(event, &handler)
@@callbacks ||= {}
@@callbacks[event] ||= []
@@callbacks[event] << handler
end
Or even:
def Button.on(event, &handler)
define_method("on_" + event, &handler)
end