Ruby Object Model – self
Leia em 1 minuto
Quando você decidiu aprender Ruby, ficou sabendo que tudo é objeto; números, classes, módulos… tudo, sem exceção, é realmente um objeto. Só que isso traz algumas implicações que nem todos conhecem. A ideia é fazer com que você realmente entenda a essência de Ruby em uma série de artigos sobre o Ruby Object Model e Metaprogramming.
Entendendo o self
self será sempre uma referência ao receiver atual e pode ser diferente dependendo do contexto em que você estiver. Por exemplo, quando estamos no namespace global, nosso self será o objeto main. Já em uma classe, nosso self será a própria classe.
puts self
#=> main
class Thing
puts self
end
#=> ThingSempre que executar um método, o Ruby irá verificar se esse método existe no receiver padrão—self— a menos que você especifique-o explicitamente. E, pelo fato de o receiver padrão ser self, você nem precisa especificá-lo se não quiser.
class Thing
def do_something
puts "doing something"
end
def do_something_else
do_something
end
endNo método do_something_else poderíamos usar self.do_something, mas isso faria com que nosso código apenas ficasse mais poluído. No entando, definir o receiver é uma coisa muito comum e que, você pode até não se dar conta, mas o faz constantemente quando escreve código Ruby.
numbers = [3,1,2]
numbers.sort
#=> [1,2,3]ou ainda
text = "some string"
text.upcase
#=> "SOME STRING"Na prática, o receiver é especificado antes do ponto na chamada de métodos, como em numbers.sort ou text.upcase.
Além de ser o receiver padrão, self também é o responsável por armazenar variáveis de instância de um objeto. Veja o exemplo abaixo.
class Person
def initialize(name)
@name = name
end
def name
@name
end
end
john = Person.new("John Doe")
john.name
#=> "John Doe"A instância da classe Person possui uma única variável de instância associada ao seu objeto—self—que é retornada pelo método name. Analogamente, podemos definir variáveis de instância em qualquer objeto, como classes.
class Person
def self.count
@count ||= 0
end
def self.count=(increment)
@count = increment
end
def initialize(name)
@name = name
self.class.count += 1
end
def name
@name
end
end
john = Person.new("John Doe")
Person.count
#=> 1O exemplo acima mostra como variáveis de instância podem ser usadas em contextos diferentes. Primeiro, estamos definindo um contador de instâncias da classe Person, cujo valor será armazenado em @count. Depois, em nossa própria instância, definimos o nome com a variável @name.
Finalizando
No próximo artigo, irei falar sobre metaclasses do Ruby. Até lá!