Será que tudo é objeto no Ruby?

em Desenvolvimento, Ruby.

Se você está inserido no mundo do Ruby, certamente já escutou algum rubysta dizer

“Em ruby tudo é objeto!”

É tão comum escutar e aceitar tal fato, pois afinal quase tudo realmente é objeto em Ruby, sim quase tudo. Objetos são os protagonistas, mas eles não estão sozinhos. Na linguagem existem também elementos que são responsáveis pela construção de sua sintaxe. Tais elementos não são objetos. Por exemplo, no caso de uma simples atribuição de variável

 

x = 10

a variável x em si não é um objeto. Variáveis referem-se a objetos, mas elas mesmas não os são. Outro exemplo bem simples são os métodos. Como muito bem explicado no livro The Ruby Programming Language de David Flanagan:

“Métodos são uma parte fundamental da sintaxe de Ruby, mas eles não são valores que os programas do ruby podem operar. Isto é, métodos em ruby não são objetos como strings, números e arrays são.”

Assim como métodos, os blocos também não são objetos. Blocos somente fazem parte da construção da chamada de um método e só podem aparecer em listas de argumentos (que por sinal também não são objetos). Vamos ao exemplo:

irb> { puts 'Não sou objeto' } # erro de sintaxe
irb> obj = { puts 'Não sou objeto } # erro de sintaxe
irb> ['obj1', 'obj2', 'obj3'].each { |obj| puts obj }
obj1
obj2
obj3
=> ["obj1", "obj2", "obj3"]

As duas primeiras linhas não vão funcionar, pois como dito, os blocos não podem aparecer em outro lugar que não seja na lista de argumentos de um método (escondi o erro de retorno para simplificar).

Já a terceira, como cumpre a regra, irá funcionar normalmente. Se blocos fossem objetos, as duas primeiras linhas estariam sintaticamente corretas. Ainda existem outros muitos exemplos como as keywords, tais quais if, class, alias, begin, end, def, etc.

Apesar de não serem objetos, todas essas estruturas sintáticas que mencionei são o que permitem criar as estruturas dentro dais quais os objetos podem ser criados e fazer tudo o que eles fazem na linguagem e por isso são elementos muito importantes.

Mesmo que alguns elementos não sejam objetos, uma verdade em Ruby é que todas as suas expressões e declarações se resultam em um.
Nem tudo é objeto, mas tudo (tudo mesmo) resulta em um

Sim tudo se resulta em objetos em Ruby, inclusive estruturas condicionais, classes, definições de métodos e tudo mais. Entender esse conceito é importante para que as algumas coisas que acontecem no seu código passem a ter mais sentido. Por exemplo, no seguinte trecho de código

irb> def foo
irb>   puts ‘hello’
irb> end.object_id

se colocado no irb resultaria no seguinte

=> 1149148 # essa id pode variar no seu computador

Estranho, não? Parece que eu acabei de escrever logo ali acima que definições de métodos não são objetos, como pode esse ter uma id de objeto? Pois bem, o que acontece ali é que ao definir o método foo, ele se resulta em um symbol que tem exatamente o nome do método e esse sim tem uma id. Vamos ver o mesmo trecho de código, porém de maneira diferente

irb> obj = def foo
irb>   puts ‘hello’
irb> end
=> :foo # retorno da definição do método
irb> obj.object_id
=> 1149148
irb> obj.class
=> Symbol

Você pode perceber eu atribui a definição do método na variável obj e essa variável então recebeu :foo, que foi o valor do retorno da definição do método. A atribuição de um valor à uma variável também se resulta em um objeto que é o valor atribuído e portanto :foo.

Como eu disse, tudo em ruby se resulta em objetos, até coisas que você não está habituado, como por exemplo definições de classes. Veja os trechos de código abaixo:

irb> class Foo; end
=> nil
irb> class Foo
irb>   def method
irb>   end
irb> end
=> :method

Como vocês já devem ter percebido, definições de classes resultam sempre no retorno da última expressão que for avaliada dentro do seu corpo ou nil para uma declaração de classe vazia. Outra expressão curiosa que também não estamos habituados a ver ter algum retorno é uma expressão condicional. Veja:

irb> if 1 > 2
irb>   “obj”
irb> end
=> nil
irb> if 2 > 1
irb>  “Obj”
irb> end
=> “obj”

Nestes casos, quando o if for falso, seu retorno sempre será nil, caso contrário, seu retorno será o objeto resultante da última expressão dentro de seu corpo.

Na maioria das vezes, os objetos resultantes de muitas das expressões de controle, classes e definições de métodos são ignorados. Porém é importante você saber que eles existem, pois em algum momento você pode vir a precisar utilizá-los ou mesmo entender porque algo está acontecendo de uma maneira que você não está conseguindo entender.

Em Ruby nem tudo são objetos, mas eles estão sempre mais próximos do que você imagina!

E, falando em Ruby, nos dias 23 e 24 de setembro, acontece na Fecomercio, em São Paulo, a RubyCOnfBR 2016! Serão 2 dias de evento com mais de 80 palestrantes e 5 trilhas sobre diversos assuntos além de Ruby, para você que deseja aprender e atualizar seus conhecimentos sobre Ruby on Rails, Devops, JavaScript, Elixir, Clojure, Go, Rust, Crystal e outras linguagens de programação. Não fique de fora do maior evento de Ruby da América Latina, inscreva-se aqui no RubyConf Brasil!

Você também pode gostar