Pergunta

Eu fui mordido um par de vezes, por esquecer que x = y em Ruby faz o x se referem ao mesmo objeto como y;Eu sou muito utilizado para idiomas que significa, em Ruby termos, x = y.dup.Esquecendo isso, eu, inadvertidamente, alterar y quando eu acho que é seguro, no lado direito da atribuição.

Eu posso ver que ele faria todo o sentido evitar o simples x = y atribuições sem um motivo especial, mas a mesma coisa pode ser à espreita, em outros lugares, como

name = (person.last_name.blank? ? 'unknown' : person.last_name)

onde posterior name << title seria, na verdade, mudando pessoa.last_name e não apenas de nome.

Se isso aconteceu com você, também, tem como você aprendeu a evitá-lo?Existem certas bandeiras vermelhas ou padrões para procurar?Você olha com desconfiança a cada tarefa que você faz?Você usa .dup um monte?Eu não sei se Ruby uso nunca vai se tornar uma segunda natureza para mim, portanto, qualquer úteis dicas seriam bem-vindos.

Foi útil?

Solução

Isso pode parecer pouco ortodoxa de uma (que é essencialmente imperativo) linguagem como Ruby, mas o meu conselho é:evitar danos colaterais por não atualizar os objetos (exceto quando estritamente necessário);criar novos vez.Você paga um pouco de desempenho, mas você vai ter o código que é mais clara, mais compacto, mais modular e fácil de depurar.

http://en.wikipedia.org/wiki/Functional_programming

Assim, no seu exemplo, basta criar uma nova string com um nome novo:

complete_name = name + title

Outras dicas

Apenas uma adição para tokland a resposta:

Abordagem funcional insiste em imutabilidade - i.e.não alterando os objetos existentes, mas a criação de outro sempre que desejar alterar o original.Isso é um pouco contra o objeto-orientado paradigma de que o Ruby também traz (objetos de manter seu estado internamente, o que pode ser alterada através de chamada de métodos), então você tem que equilibrar um pouco entre as duas abordagens (por outro lado, nós nos beneficiamos por ter vários paradigmas facilmente acessíveis em um único idioma).

Então, três coisas para lembrar para agora:

  1. Saiba o que a atribuição em Ruby é:nada, mas a nomeação de um objeto.Então, quando você diz y=x, você está apenas dizendo: "nós damos outro nome y para o que foi chamado x".
  2. name << title as mutações do objeto chamado name.
  3. name += title leva objetos nomeados name e title, concatena-las em outro objeto e atribui novo nome do objeto name.Ele não modifica nada.

Eu também me deparei com tal situação e isso resultou em um erro, que eu levei metade de um dia para descobrir.Essencialmente eu fiz algo parecido com isto

hash = {....}
filename = object.file_name
hash.each |k, v| {file_name.gsub!(k, v) if file_name.include? k}

Este código foi dentro de um loop e loop, eu esperava que a variável file_name para ser novamente ajustado para o valor original.Mas o objeto.file_name foi alterado, como eu estava realizando file_name.gsub!.Existem 2 maneiras de resolver isso.Substituir o .gsub! chamada com file_name = file_name.gsub ou fazer file_name = object.file_name.dup.Optei pela segunda opção.

Eu acho que devemos ter cuidado com os métodos tenham ! e <<, como elas mudam o objeto original em que estão atuando, especialmente depois de atribuições como este.

Um método não deve modificar uma variável (por exemplo,usando o operador shift), a menos que a sua definição diz que vai modificá-lo.

Assim:nunca modificar um objeto em um método que não o (a) criar ou (b) documento que modifica-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top