Los documentos de Ruby paradup decir:
En general,
cloneyduppuede tener una semántica diferente en las clases descendientes. Mientrasclonese usa para duplicar un objeto, incluido su estado interno,dupgeneralmente usa la clase del objeto descendiente para crear la nueva instancia.
Pero cuando hago alguna prueba descubrí que en realidad son lo mismo:
class Test
attr_accessor :x
end
x = Test.new
x.x = 7
y = x.dup
z = x.clone
y.x => 7
z.x => 7
Entonces, ¿cuáles son las diferencias entre los dos métodos?

dupy quéclonehace, sino por qué usaría uno en lugar del otro.Respuestas:
Las subclases pueden anular estos métodos para proporcionar una semántica diferente. En
Objectsí mismo, hay dos diferencias clave.Primero,
clonecopia la clase singleton, mientrasdupque no.En segundo lugar,
cloneconserva el estado congelado, mientrasdupque no.La implementación de Rubinius para estos métodos es a menudo mi fuente de respuestas a estas preguntas, ya que es bastante clara y una implementación de Ruby bastante compatible.
fuente
o = Object.new; class << o; A=5; end; puts ( class << o.clone; A; end ); puts ( class << o.dup; A; end ).extendeditado en el objeto original. EntoncesObject.new.extend(Enumerable).dup.is_a?(Enumerable)devuelve falso.Cuando se trata de ActiveRecord también hay una diferencia significativa:
dupcrea un nuevo objeto sin que se establezca su ID, por lo que puede guardar un nuevo objeto en la base de datos presionando.saveclonecrea un nuevo objeto con la misma identificación, por lo que todos los cambios realizados en ese nuevo objeto sobrescribirán el registro original si se presiona.savefuente
dupyclonemétodos en miActiveRecordobjeto, obtengo resultados inversos de lo que has mencionado en la respuesta. lo que significa que cuando estoy usandodup, crea un nuevo objeto con el que seidestá configurando y mientras lo usaclonecrea un objeto sin queidse configure. ¿Puedes por favor mirarlo nuevamente y aclararlo? . Thnxclonecrear un nuevo registro que nunca se haya guardado debería ser bastante seguro? ¿Puedo construir un "objeto de plantilla" de esta manera y clonarlo para guardar instancias específicas?Una diferencia es con los objetos congelados. El
clonede un objeto congelado también está congelado (mientras que eldupde un objeto congelado no lo está).Otra diferencia es con los métodos singleton. La misma historia aquí,
dupno copia esos, peroclonesí.fuente
Ambos son casi idénticos, pero el clon hace una cosa más que dup. En clon, el estado congelado del objeto también se copia. En dup, siempre estará descongelado.
fuente
El documento más reciente incluye un buen ejemplo:
fuente
Puedes usar clone para hacer programación basada en prototipos en Ruby. La clase Object de Ruby define tanto el método de clonación como el método dup. Tanto clone como dup producen una copia superficial del objeto que está copiando; es decir, las variables de instancia del objeto se copian pero no los objetos a los que hacen referencia. Voy a demostrar un ejemplo:
Observe que en el ejemplo anterior, el clon naranja copia el estado (es decir, las variables de instancia) del objeto apple, pero cuando el objeto apple hace referencia a otros objetos (como el color del objeto String), esas referencias no se copian. En cambio, ¡manzana y naranja hacen referencia al mismo objeto! En nuestro ejemplo, la referencia es el objeto de cadena 'rojo'. Cuando orange usa el método append, <<, para modificar el objeto String existente, cambia el objeto string a 'red orange'. En efecto, esto también cambia apple.color, ya que ambos apuntan al mismo objeto String.
Como nota al margen, el operador de asignación, =, asignará un nuevo objeto y, por lo tanto, destruirá una referencia. Aquí hay una demostración:
En el ejemplo anterior, cuando asignamos un nuevo objeto nuevo al método de instancia de color del clon naranja, ya no hace referencia al mismo objeto que la manzana. Por lo tanto, ahora podemos modificar el método de color naranja sin afectar el método de color de apple, pero si clonamos otro objeto de apple, ese nuevo objeto hará referencia a los mismos objetos en las variables de instancia copiadas como apple.
dup también producirá una copia superficial del objeto que está copiando, y si hiciera la misma demostración que se muestra arriba a dup, verá que funciona exactamente de la misma manera. Pero hay dos diferencias principales entre clonar y dup. Primero, como otros mencionaron, clone copia el estado congelado y dup no. ¿Qué significa esto? El término 'congelado' en Ruby es un término esotérico para inmutable, que en sí mismo es una nomenclatura en informática, lo que significa que algo no puede cambiarse. Por lo tanto, un objeto congelado en Ruby no puede modificarse de ninguna manera; es, en efecto, inmutable. Si intenta modificar un objeto congelado, Ruby generará una excepción RuntimeError. Dado que clonar copia el estado congelado, si intenta modificar un objeto clonado, generará una excepción RuntimeError. Por el contrario, dado que dup no copia el estado congelado,
En segundo lugar, y, más interesante, ¡el clon copia la clase singleton (y por lo tanto sus métodos)! Esto es muy útil si desea realizar una programación basada en prototipos en Ruby. Primero, demostremos que, de hecho, los métodos singleton se copian con clon, y luego podemos aplicarlo en un ejemplo de programación basada en prototipos en Ruby.
Como puede ver, la clase singleton de la instancia del objeto de fruta se copia en el clon. Y, por lo tanto, el objeto clonado tiene acceso al método singleton: ¿sembrado ?. Pero este no es el caso con dup:
Ahora, en la programación basada en prototipos, no tiene clases que extiendan otras clases y luego cree instancias de clases cuyos métodos se derivan de una clase principal que sirve como modelo. En cambio, tiene un objeto base y luego crea un nuevo objeto a partir del objeto con sus métodos y estado copiados (por supuesto, dado que estamos haciendo copias superficiales a través de clon, cualquier objeto al que se haga referencia de variables de instancia se compartirá tal como en JavaScript prototipos). Luego puede completar o cambiar el estado del objeto completando los detalles de los métodos clonados. En el siguiente ejemplo, tenemos un objeto de fruta base. Todas las frutas tienen semillas, por lo que creamos un método number_of_seeds. Pero las manzanas tienen una semilla, por lo que creamos un clon y completamos los detalles. Ahora cuando clonamos manzana, ¡no solo clonamos los métodos sino que clonamos el estado! Recuerde que el clon hace una copia superficial del estado (variables de instancia). Y por eso, cuando clonemos una manzana para obtener una manzana roja, ¡la manzana roja automáticamente tendrá 1 semilla! Puedes pensar en red_apple como un objeto que hereda de Apple, que a su vez hereda de Fruit. Por eso, capitalicé Fruit and Apple. Eliminamos la distinción entre clases y objetos por cortesía del clon.
Por supuesto, podemos tener un método constructor en la programación basada en prototipos:
En última instancia, utilizando clone, puede obtener algo similar al comportamiento del prototipo de JavaScript.
fuente