Ruby Object Model – self
29/09/10
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
#=> Thing
Sempre 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
end
No 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
#=> 1
O 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á!
- Permalink
- Trackback
- Comentários (5)
- Ao som de: Sum 41 – The Hell Song
Textos escritos por
Comentários #
[...] This post was mentioned on Twitter by Diego R. V., Carlos Antonio and emerson vinicius, Vinícius Oliveira. Vinícius Oliveira said: RT @cantoniodasilva: primeiro artigo de uma série sobre ruby object model e metaprogramming ~ http://bit.ly/ahMdSD (via @fnando) [...]
parabens pela iniciativa
abraco
Belo post.
quer dizer que quando faço isso
class Person
def self.count
@count ||= 0
end
end
estou definindo count a Class Person e não ao meu objeto é isso?
Isso mesmo! A variável de instância sempre estará atrelada a um objeto representado pelo self e que neste caso é uma classe.
[...] artigo anterior eu mostrei como o self muda em diferentes contextos. Neste artigo, você verá o que são as [...]
Deixe um comentário