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á!

Comentários #

#1 Tweets that mention Ruby Object Model – self — Simples Ideias... disse:
29 Set 10, 11:06AM

[...] 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) [...]

#2 mairon disse:
29 Set 10, 11:15AM

parabens pela iniciativa

abraco

#3 Emerson Vinicius disse:
29 Set 10, 12:53PM

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?

#4 Nando Vieira disse:
29 Set 10, 04:24PM

Isso mesmo! A variável de instância sempre estará atrelada a um objeto representado pelo self e que neste caso é uma classe.

#5 Ruby Object Model – Singleton Class — Simples Ideias. Por... disse:
30 Set 10, 10:30AM

[...] artigo anterior eu mostrei como o self muda em diferentes contextos. Neste artigo, você verá o que são as [...]

Deixe um comentário





Não é aceito código HTML: adicione-o no pastie.org ou paste.milk-it.net e poste apenas o link.

Se este é seu primeiro comentário, ele terá que ser aprovado antes de ser exibido.

jQuery: Dominando o framework

Você quer aprender a usar jQuery de verdade? Então chegou a hora! Neste workshop você verá como funciona este framework de JavaScript, entendendo todos os aspectos que fazem do jQuery uma das melhores ferramentas para desenvolvimento de interfaces.

Saiba mais Fechar

Conheça também o HOWTO