Palavras-chave: object_id, negativo, __id__
Em Ruby, bem como em outras linguagens que trabalham orientadas a objetos, existe o conceito do ObjectID (ou id de objeto), que nada mais é do que uma identificação única para um objeto instanciado dentro de uma aplicação.
Para ter acesso ao ObjectID em Ruby basta utilizar o método object_id
ou __id__
. De acordo com a própria documentação da linguagem, o método retorna “um identificador inteiro do objeto. Esse número será retornado em todas as chamadas ao objeto e dois objetos ativos nunca compartilharão o mesmo id.”
Nada demais. Contudo, existe uma peculiaridade nessa definição que às vezes é passada despercebida:
$ ruby -e "class Foo; end; f = Foo.new; p f; puts f.object_id;" #<Foo:0xb7d921c8> -605253404
O trecho de código acima cria uma instância da class Foo e imprime o endereçamento da memória onde o objeto foi alocado, juntamento com seu respectivo ObjectID. Observou o número negativo? Ele é a representação inteira da posição da memória do objeto. (0xb7d921c8 <-> -605253404).
Assim, o ObjectID em Ruby é sempre um número inteiro, positivo ou negativo.
Tudo bem Masaru
Olhe o seguinte exemplo no irb:
a = 1
=>1
a.object_id
=>3
b = 1
=> 1
b.object_id
=>3
Nesse caso tenho dois objetos só que com o mesmo identificador. Será que tem a ver com o Duck Type no qual se parece com um pato então deve ser um pato, ou seja, se são objetos diferentes mas com o mesmo valor então deve-se utilizar o mesmo identificador.
Bom vamos discutir até chegar a alguma explicação mais detalhada ainda estou somente com suposições
Até mais.
Valério, eles tem o mesmo object_id pois são immediate values, que armazenam o valor, e não a referência de um objeto em seu object_id.
Dá uma olhada nessas duas dicas:
https://codare.aurelio.net/2007/02/06/ruby-obter-valor-de-um-fixnum-pelo-seu-object_id
https://codare.aurelio.net/2007/01/25/ruby-revelar-objetos-fixnum-pelo-seu-object-id/
Valério: no caso que você mostrou não são objetos diferentes. a e b são variáveis que apontam para o mesmo objeto: o número 1.
Na verdade nem há objetos ali para serem apontados. A única referência é para a classe Fixnum, mas alocação de um objeto explícito para o 1 não existe.
Em Python isso acontece também e é um mecanismo de optimização da linguagem. Deve acontecer a mesma coisa com o Ruby. A regra é mais ou menos assim:
Constantes de objetos imutáveis (strings, inteiros, ponto-flutuante, etc) são criadas uma única vez e então referenciadas.
Isso acontece com strings também e é por isso que devemos usar o “is” com cuidado :)
Isso também é uma característica da implementação do interpretador usado, ou seja, ser assim no CPython não garante que o mesmo aconteça no Jython ou no IronPython.