Blog do Phil

Tecnologia e opinião

Declaração de variável no Ruby: por valor ou referência?

Toda declaração de variável na linguagem Ruby é feita por referência. Isso significa que quando declaramos uma variável, na verdade estamos declarando uma referência para um objeto em memória. Essa informação parece ser básica e dificilmente você terá problemas com isso. Mas aconteceu comigo, onde por engano eu esqueci deste pequeno detalhe.

Meu caso foi com um código mais ou menos como o abaixo.

1
2
3
4
5
6
7
8
9
a = [1, 2, 3, 4]
b = a
b << 5
puts b
#=> [1, 2, 3, 4, 5]
puts a
#=> [1, 2, 3, 4, 5]
puts a.object_id == b.object_id
#=> true

O código não era tão simples, mas o exemplo ilustra bem como aconteceu. Meu intuito era trabalhar com o conteúdo “armazenado” em b e deixar o conteúdo em a intacto. Porém quando alterei o valor de b (adicionando 5), também alterei em a. Isso causou um bug que foi corrigido no processo de code review.

Isso porque em Ruby todas as declarações são feitas através de referências para objetos.

Para resolver possíveis problemas (como alterar acidentalmente o objeto errado), você pode “clonar” ou “duplicar” (veja a diferença nos links abaixo) um objeto quando for referenciá-lo a uma variável.

Exemplo:

1
2
3
4
5
6
7
8
9
a = [1, 2, 3, 4]
b = a.dup
b << 5
puts b
#=> [1, 2, 3, 4, 5]
puts a
#=> [1, 2, 3, 4]
puts a.object_id == b.object_id
#=> false

Alguns links do Stack Overflow sobre o assunto:

Comments