Pergunta

arr = ["red","green","yellow"]

arr2 = arr.clone
arr2[0].replace("blue")

puts arr.inspect
puts arr2.inspect

produz:

["blue", "green", "yellow"]
["blue", "green", "yellow"]

De qualquer forma, existe uma cópia profunda de uma variedade de cordas, além de usar o Marshal, como eu entendo que é um hack.

Eu poderia fazer:

arr2 = []
arr.each do |e|
  arr2 << e.clone
end

Mas não parece muito elegante ou eficiente.

Obrigado

Foi útil?

Solução

Sua segunda solução pode ser reduzida para arr2 = arr.map do |e| e.dup end (a menos que você realmente precise do comportamento de clone, é recomendável usar dup em vez de).

Fora isso, suas duas soluções são basicamente as soluções padrão para executar uma cópia profunda (embora a segunda versão seja de apenas um nível de profundidade (ou seja, se você a usar em uma matriz de matrizes, você ainda poderá mudar as seqüências)). Não há realmente uma maneira mais agradável.

EDIT: Aqui está um método de Deep_Dup recursivo que funciona com matrizes arbitrariamente aninhadas:

class Array
  def deep_dup
    map {|x| x.deep_dup}
  end
end

class Object
  def deep_dup
    dup
  end
end

class Numeric
  # We need this because number.dup throws an exception
  # We also need the same definition for Symbol, TrueClass and FalseClass
  def deep_dup
    self
  end
end

Você também pode definir Deep_Dup para outros contêineres (como hash); caso contrário, você ainda obterá uma cópia superficial para eles.

Outras dicas

Eu recomendo sua ideia inicial, mas escrito um pouco mais concisamente:

arr = ["red","green","yellow"]
arr2 = arr.inject([]) { |a,element| a << element.dup }

Estou em uma situação semelhante e muito preocupada com a velocidade. A maneira mais rápida de mim foi fazer uso de map{&:clone}

Então tente isto:

pry(main)> a = (10000..1000000).to_a.shuffle.map(&:to_s)
pry(main)> Benchmark.ms { b = a.deep_dup }                                                                                     
=> 660.7760030310601
pry(main)> Benchmark.ms { b = a.join("--!--").split("--!--") }
=> 605.0828141160309
pry(main)> Benchmark.ms { b = a.map(&:clone) }
=> 450.8283680770546

Se os dados da sessão for armazenado no banco de dados e O cookie de sessão é criptografado, usando os dados da sessão é muito seguro.

O cookie da sessão só detém o ID da sessão, o agente do usuário e o endereço IP.Além disso, a sessão expira a cada 5 minutos (por padrão), por isso, para highjack, a sessão, alguém precisa quebrar a criptografia de cookie, defina o IP e o agente do usuário para o armazenado no cookie e faça tudo isso no 5minutos de janela antes que o ID da sessão seja alterado.

Isso é altamente improvável (na minha opinião).

Você também pode permitir ativar a opção de falsificação de solicitação de Site Cross (CSRF) no seu arquivo de configuração para aumentar sua segurança do formulários (embora nada substitui a validação adequada dos usuários)

Parece tão simples .. basta executar o código abaixo:

a = [1,2,3]
b = [].replace(a)

b[1] = 5

puts a
puts b

Execute o código acima e você notará a diferença. Felicidades !

Você pode usar este hack:

arr1 = %w{ red green blue }
arr2 = arr1.join("--!--").split("--!--")

Mas é só por diversão :)

arr2[0].replace("lol")
p arr1
#=> ["red", "green", "blue"]
p arr2
#=> ["lol", "green", "blue"]

E funcionará apenas para 1 nível de matrizes

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