class MinhaClasse
def metodo
# meu método
end
end
What is happening here is quite simple: You are creating an instance method in the class MinhaClasse
. Nothing out of the ordinary.
class MinhaClasse
outro_metodo
end
Already when you write this, is calling the method outro_metodo
in the object self
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 thus:
def MinhaClasse.outro_metodo
# código
end
Or so, in an equivalent way:
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 last block as its implementation. Something like that:
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 the define_method
, which is a class method 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 usage, metaprogramming! This allows you to create "special" behavior syntax, and make the language behave as you wish. 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
Good explanation. Sanou my doubts. Thanks!
– user7261