https://foro.elhacker.net/programacion_general/iquestque_metodo_es_recomendado_para_ordenar_al_azar_un_array-t522940.0.html
...quería agregarle eficientemente que el nuevo array pudiera tener menos elementos que el original. Como no se me ocurrió bien cómo, consulté a GPT:
En Macromedia Flash 5 tengo un array de 3 elementos y quiero que se genere otro array con 2 de esos elementos al azar, y ordenados al azar ¿cómo?
Citar
En **Macromedia Flash 5**, puedes usar `ActionScript` para lograr lo que necesitas: generar un nuevo array con dos elementos seleccionados al azar del array original, y luego ordenarlos aleatoriamente. Aquí tienes un ejemplo de código que hace exactamente eso:
```actionscript
// Array original con 3 elementos
var originalArray = ["Elemento1", "Elemento2", "Elemento3"];
// Función para seleccionar 2 elementos al azar del array original
function getRandomElements(array) {
// Copiar el array original para no modificarlo
var tempArray = array.slice(0);
var randomArray = [];
// Seleccionar 2 elementos al azar
for (var i = 0; i < 2; i++) {
var randomIndex = Math.floor(Math.random() * tempArray.length);
randomArray.push(tempArray[randomIndex]);
// Remover el elemento seleccionado para evitar duplicados
tempArray.splice(randomIndex, 1);
}
// Mezclar los elementos seleccionados
randomArray.sort(function() {
return Math.random() - 0.5;
});
return randomArray;
}
// Generar el nuevo array con 2 elementos al azar y ordenados al azar
var newArray = getRandomElements(originalArray);
// Mostrar el resultado
trace("Array original: " + originalArray);
trace("Nuevo array: " + newArray);
```
### Explicación del código:
1. **Copia del array original**:
- Usamos `slice(0)` para crear una copia del array original, de modo que no lo modifiquemos al eliminar elementos.
2. **Selección aleatoria**:
- En el loop, se seleccionan dos elementos al azar usando `Math.random()` y se eliminan del array temporal (`tempArray`) con `splice()`, para evitar duplicados.
3. **Orden aleatorio**:
- Usamos `sort()` con una función de comparación que devuelve un valor aleatorio para mezclar los elementos seleccionados.
4. **Resultado**:
- El nuevo array (`newArray`) contiene dos elementos seleccionados al azar del array original, y están ordenados de manera aleatoria.
### Ejemplo de salida:
Si el array original es `["Elemento1", "Elemento2", "Elemento3"]`, la salida podría ser algo como:
```
Array original: Elemento1,Elemento2,Elemento3
Nuevo array: Elemento2,Elemento1
```
Cada vez que ejecutes el código, la selección y el orden serán diferentes.
```actionscript
// Array original con 3 elementos
var originalArray = ["Elemento1", "Elemento2", "Elemento3"];
// Función para seleccionar 2 elementos al azar del array original
function getRandomElements(array) {
// Copiar el array original para no modificarlo
var tempArray = array.slice(0);
var randomArray = [];
// Seleccionar 2 elementos al azar
for (var i = 0; i < 2; i++) {
var randomIndex = Math.floor(Math.random() * tempArray.length);
randomArray.push(tempArray[randomIndex]);
// Remover el elemento seleccionado para evitar duplicados
tempArray.splice(randomIndex, 1);
}
// Mezclar los elementos seleccionados
randomArray.sort(function() {
return Math.random() - 0.5;
});
return randomArray;
}
// Generar el nuevo array con 2 elementos al azar y ordenados al azar
var newArray = getRandomElements(originalArray);
// Mostrar el resultado
trace("Array original: " + originalArray);
trace("Nuevo array: " + newArray);
```
### Explicación del código:
1. **Copia del array original**:
- Usamos `slice(0)` para crear una copia del array original, de modo que no lo modifiquemos al eliminar elementos.
2. **Selección aleatoria**:
- En el loop, se seleccionan dos elementos al azar usando `Math.random()` y se eliminan del array temporal (`tempArray`) con `splice()`, para evitar duplicados.
3. **Orden aleatorio**:
- Usamos `sort()` con una función de comparación que devuelve un valor aleatorio para mezclar los elementos seleccionados.
4. **Resultado**:
- El nuevo array (`newArray`) contiene dos elementos seleccionados al azar del array original, y están ordenados de manera aleatoria.
### Ejemplo de salida:
Si el array original es `["Elemento1", "Elemento2", "Elemento3"]`, la salida podría ser algo como:
```
Array original: Elemento1,Elemento2,Elemento3
Nuevo array: Elemento2,Elemento1
```
Cada vez que ejecutes el código, la selección y el orden serán diferentes.
¿por qué pones
var tempArray = array.slice(0);
en vez de
tempArray = array;
?
Citar
La razón por la que usé:
```actionscript
var tempArray = array.slice(0);
```
en lugar de:
```actionscript
tempArray = array;
```
es para **crear una copia del array original**, en lugar de simplemente referenciarlo.
### Diferencia entre copiar y referenciar un array:
- **`tempArray = array;`**
Esto no crea un nuevo array. En lugar de ello, `tempArray` apunta al mismo espacio de memoria que el array original (`array`). Si modificas `tempArray` (como eliminar elementos con `splice()`), también estarás modificando el array original, porque ambos comparten el mismo contenido.
- **`tempArray = array.slice(0);`**
Esto crea una **copia del array original**. Cualquier cambio que hagas en `tempArray` no afectará al array original, ya que ahora son dos arrays independientes.
### ¿Por qué es importante en este caso?
En el código, usamos `splice()` para eliminar elementos del array temporal (`tempArray`) mientras seleccionamos elementos aleatorios. Si no hacemos una copia (usando `slice()`), también estaríamos eliminando elementos del array original, lo cual probablemente no sea lo que queremos.
### Ejemplo práctico:
Supongamos que tienes este código:
```actionscript
var originalArray = ["Elemento1", "Elemento2", "Elemento3"];
var tempArray = originalArray;
// Modificar tempArray
tempArray.splice(0, 1);
// Imprimir ambos arrays
trace("originalArray: " + originalArray);
trace("tempArray: " + tempArray);
```
**Salida:**
```
originalArray: Elemento2,Elemento3
tempArray: Elemento2,Elemento3
```
Como ves, al modificar `tempArray`, también se modifica `originalArray`, porque ambos apuntan al mismo array.
Ahora, usando `slice(0)`:
```actionscript
var originalArray = ["Elemento1", "Elemento2", "Elemento3"];
var tempArray = originalArray.slice(0);
// Modificar tempArray
tempArray.splice(0, 1);
// Imprimir ambos arrays
trace("originalArray: " + originalArray);
trace("tempArray: " + tempArray);
```
**Salida:**
```
originalArray: Elemento1,Elemento2,Elemento3
tempArray: Elemento2,Elemento3
```
Aquí, `originalArray` permanece intacto, porque `tempArray` es una copia independiente.
### Conclusión:
Usar `slice(0)` asegura que puedas trabajar con un array temporal sin modificar el array original. Esto es crucial cuando necesitas preservar el estado del array original para otros usos o simplemente para evitar efectos secundarios no deseados.
```actionscript
var tempArray = array.slice(0);
```
en lugar de:
```actionscript
tempArray = array;
```
es para **crear una copia del array original**, en lugar de simplemente referenciarlo.
### Diferencia entre copiar y referenciar un array:
- **`tempArray = array;`**
Esto no crea un nuevo array. En lugar de ello, `tempArray` apunta al mismo espacio de memoria que el array original (`array`). Si modificas `tempArray` (como eliminar elementos con `splice()`), también estarás modificando el array original, porque ambos comparten el mismo contenido.
- **`tempArray = array.slice(0);`**
Esto crea una **copia del array original**. Cualquier cambio que hagas en `tempArray` no afectará al array original, ya que ahora son dos arrays independientes.
### ¿Por qué es importante en este caso?
En el código, usamos `splice()` para eliminar elementos del array temporal (`tempArray`) mientras seleccionamos elementos aleatorios. Si no hacemos una copia (usando `slice()`), también estaríamos eliminando elementos del array original, lo cual probablemente no sea lo que queremos.
### Ejemplo práctico:
Supongamos que tienes este código:
```actionscript
var originalArray = ["Elemento1", "Elemento2", "Elemento3"];
var tempArray = originalArray;
// Modificar tempArray
tempArray.splice(0, 1);
// Imprimir ambos arrays
trace("originalArray: " + originalArray);
trace("tempArray: " + tempArray);
```
**Salida:**
```
originalArray: Elemento2,Elemento3
tempArray: Elemento2,Elemento3
```
Como ves, al modificar `tempArray`, también se modifica `originalArray`, porque ambos apuntan al mismo array.
Ahora, usando `slice(0)`:
```actionscript
var originalArray = ["Elemento1", "Elemento2", "Elemento3"];
var tempArray = originalArray.slice(0);
// Modificar tempArray
tempArray.splice(0, 1);
// Imprimir ambos arrays
trace("originalArray: " + originalArray);
trace("tempArray: " + tempArray);
```
**Salida:**
```
originalArray: Elemento1,Elemento2,Elemento3
tempArray: Elemento2,Elemento3
```
Aquí, `originalArray` permanece intacto, porque `tempArray` es una copia independiente.
### Conclusión:
Usar `slice(0)` asegura que puedas trabajar con un array temporal sin modificar el array original. Esto es crucial cuando necesitas preservar el estado del array original para otros usos o simplemente para evitar efectos secundarios no deseados.
Poner un nombre, luego = y luego un valor, es crear una variable cuyo nombre es el indicado en nombre y su valor es indicado luego del signo =, no es una referencia ¿o estoy equivocado?
Citar
Estás en lo correcto en términos generales: cuando haces algo como:
```actionscript
var nombre = valor;
```
estás creando una variable llamada `nombre` y asignándole el valor de `valor`. Sin embargo, **el comportamiento de la variable depende del tipo de dato que estés asignando**. En ActionScript (y en muchos lenguajes de programación), los tipos de datos se dividen principalmente en dos categorías:
1. **Tipos primitivos** (números, cadenas, booleanos, etc.).
2. **Tipos complejos o de referencia** (objetos, arrays, etc.).
La diferencia clave radica en cómo se asignan y manejan los valores en memoria.
---
### Tipos primitivos: Copia del valor
Cuando asignas un tipo primitivo a una variable, se copia su valor directamente en la nueva variable. Por ejemplo:
```actionscript
var a = 5;
var b = a;
b = 10;
trace(a); // 5
trace(b); // 10
```
Aquí, `a` y `b` son independientes, porque el número `5` (un tipo primitivo) se copió en `b`. Cambiar `b` no afecta a `a`.
---
### Tipos complejos (como arrays): Referencia en memoria
Cuando trabajas con tipos complejos, como arrays u objetos, lo que realmente estás asignando no es el "valor" en sí, sino una **referencia en memoria** al lugar donde se almacenan esos datos. Esto significa que si usas el operador `=` para asignar un array a otra variable, ambas variables apuntarán al mismo array en memoria. Por ejemplo:
```actionscript
var originalArray = [1, 2, 3];
var otherArray = originalArray;
otherArray.push(4);
trace(originalArray); // [1, 2, 3, 4]
trace(otherArray); // [1, 2, 3, 4]
```
Aquí, tanto `originalArray` como `otherArray` apuntan al mismo array en memoria. Al modificar `otherArray`, también estás modificando `originalArray`.
Si quieres evitar este comportamiento y trabajar con una copia independiente del array, necesitas crear una copia explícita, como con el método `slice()`:
```actionscript
var originalArray = [1, 2, 3];
var otherArray = originalArray.slice(0);
otherArray.push(4);
trace(originalArray); // [1, 2, 3]
trace(otherArray); // [1, 2, 3, 4]
```
Ahora, `originalArray` y `otherArray` son arrays completamente separados, y los cambios en uno no afectan al otro.
---
### Conclusión
Cuando haces:
```actionscript
tempArray = array;
```
no estás creando un nuevo array. Estás haciendo que `tempArray` apunte al mismo array en memoria que `array`. Por eso, cualquier cambio que hagas en `tempArray` también se verá reflejado en `array`.
Si quisieras que `tempArray` sea una copia independiente del contenido de `array` (sin afectar al original), necesitas usar algo como:
```actionscript
tempArray = array.slice(0);
```
Esto crea un nuevo array con el mismo contenido, pero almacenado en un espacio de memoria diferente.
En resumen: la diferencia entre **valor** y **referencia** es lo que causa este comportamiento.
```actionscript
var nombre = valor;
```
estás creando una variable llamada `nombre` y asignándole el valor de `valor`. Sin embargo, **el comportamiento de la variable depende del tipo de dato que estés asignando**. En ActionScript (y en muchos lenguajes de programación), los tipos de datos se dividen principalmente en dos categorías:
1. **Tipos primitivos** (números, cadenas, booleanos, etc.).
2. **Tipos complejos o de referencia** (objetos, arrays, etc.).
La diferencia clave radica en cómo se asignan y manejan los valores en memoria.
---
### Tipos primitivos: Copia del valor
Cuando asignas un tipo primitivo a una variable, se copia su valor directamente en la nueva variable. Por ejemplo:
```actionscript
var a = 5;
var b = a;
b = 10;
trace(a); // 5
trace(b); // 10
```
Aquí, `a` y `b` son independientes, porque el número `5` (un tipo primitivo) se copió en `b`. Cambiar `b` no afecta a `a`.
---
### Tipos complejos (como arrays): Referencia en memoria
Cuando trabajas con tipos complejos, como arrays u objetos, lo que realmente estás asignando no es el "valor" en sí, sino una **referencia en memoria** al lugar donde se almacenan esos datos. Esto significa que si usas el operador `=` para asignar un array a otra variable, ambas variables apuntarán al mismo array en memoria. Por ejemplo:
```actionscript
var originalArray = [1, 2, 3];
var otherArray = originalArray;
otherArray.push(4);
trace(originalArray); // [1, 2, 3, 4]
trace(otherArray); // [1, 2, 3, 4]
```
Aquí, tanto `originalArray` como `otherArray` apuntan al mismo array en memoria. Al modificar `otherArray`, también estás modificando `originalArray`.
Si quieres evitar este comportamiento y trabajar con una copia independiente del array, necesitas crear una copia explícita, como con el método `slice()`:
```actionscript
var originalArray = [1, 2, 3];
var otherArray = originalArray.slice(0);
otherArray.push(4);
trace(originalArray); // [1, 2, 3]
trace(otherArray); // [1, 2, 3, 4]
```
Ahora, `originalArray` y `otherArray` son arrays completamente separados, y los cambios en uno no afectan al otro.
---
### Conclusión
Cuando haces:
```actionscript
tempArray = array;
```
no estás creando un nuevo array. Estás haciendo que `tempArray` apunte al mismo array en memoria que `array`. Por eso, cualquier cambio que hagas en `tempArray` también se verá reflejado en `array`.
Si quisieras que `tempArray` sea una copia independiente del contenido de `array` (sin afectar al original), necesitas usar algo como:
```actionscript
tempArray = array.slice(0);
```
Esto crea un nuevo array con el mismo contenido, pero almacenado en un espacio de memoria diferente.
En resumen: la diferencia entre **valor** y **referencia** es lo que causa este comportamiento.
¿Por qué lo hicieron así?
Citar
Implementar arrays y objetos como **tipos por referencia** en lenguajes como ActionScript (y otros lenguajes como javascript, Python, etc.) no es algo arbitrario, tiene razones prácticas y de diseño. Aquí te explico por qué **los arrays y objetos funcionan por referencia** y no como copias directas:
---
## 1. **Eficiencia en memoria y rendimiento**
Cuando trabajas con tipos complejos como arrays u objetos, estos pueden contener grandes cantidades de información. Si cada vez que los asignaras a una nueva variable se hiciera una copia completa de los datos, esto consumiría mucha memoria y sería muy lento.
Por ejemplo, considera este caso:
```actionscript
var arrayGrande = [1, 2, 3, ..., 100000]; // Un array con 100,000 elementos
var copia = arrayGrande; // ¿Qué pasaría si fuera una copia completa?
```
Si el lenguaje copiara todo el array al asignarlo, el programa tendría que:
1. Reservar **el doble** de espacio en memoria para almacenar los mismos datos.
2. Copiar cada uno de los 100,000 elementos al nuevo array.
Esto haría que las operaciones de asignación fueran lentas y que el uso de memoria se disparara rápidamente en aplicaciones que manejan muchos datos.
**Por referencia**, en cambio, el lenguaje simplemente crea un "puntero" o "referencia" al espacio de memoria donde ya está almacenado el array. Esto es mucho más rápido y eficiente porque no duplica los datos, sino que solo comparte la referencia.
---
## 2. **Facilita la mutabilidad**
Cuando trabajas con objetos y arrays, muchas veces necesitas que todos los cambios se reflejen en el mismo lugar. Si los arrays fueran siempre copiados al asignarlos, sería complicado coordinar los cambios entre diferentes partes de tu código.
Por ejemplo:
```actionscript
var config = { ancho: 800, alto: 600 };
var referencia = config;
referencia.ancho = 1024;
trace(config.ancho); // 1024
```
Aquí, tanto `config` como `referencia` apuntan al mismo objeto. Si cambias un valor en `referencia`, también se refleja en `config`, porque ambos son referencias al mismo objeto. Esto facilita que múltiples variables o funciones trabajen con los mismos datos sin necesidad de copiar y sincronizar los cambios manualmente.
Si los objetos fueran copiados automáticamente, el cambio en `referencia` no afectaría a `config`, y tendrías que buscar formas más complicadas de mantenerlos sincronizados.
---
## 3. **Es coherente con el diseño de programación orientada a objetos**
Los lenguajes como ActionScript están diseñados para manejar objetos de manera flexible. En este paradigma, los objetos y arrays suelen comportarse como entidades compartidas, **en lugar de duplicarse automáticamente**. Esto es clave para trabajar con estructuras de datos dinámicas, como listas enlazadas, árboles, o gráficos, donde las relaciones entre los elementos son importantes.
Por ejemplo:
```actionscript
var nodo1 = { valor: 1, siguiente: null };
var nodo2 = { valor: 2, siguiente: nodo1 };
trace(nodo2.siguiente.valor); // 1
```
Este tipo de estructuras serían mucho más difíciles de implementar si cada asignación hiciera copias completas de los datos.
---
## 4. **Consistencia con otros lenguajes**
ActionScript heredó muchas de sus características de javascript (que, a su vez, está inspirado en otros lenguajes como Java). En todos estos lenguajes, los objetos y arrays funcionan por referencia. Esto hace que el comportamiento sea predecible y **consistente con el estándar de la industria**, lo que facilita a los programadores aprender y trabajar con lenguajes similares.
---
## ¿Por qué no hacerlo todo por valor?
Si trabajar por referencia es tan eficiente, podrías preguntarte por qué no todos los tipos de datos funcionan así. La razón es que **los tipos primitivos (como números, cadenas y booleanos)** son mucho más simples y pequeños en términos de tamaño en memoria. Duplicarlos no es costoso y, en la mayoría de los casos, es más útil que sean independientes.
Por ejemplo:
```actionscript
var a = 5;
var b = a;
b = 10;
trace(a); // Todavía es 5
trace(b); // Es 10
```
En este caso, trabajar **por valor** tiene sentido porque los números son pequeñas cantidades de datos y se espera que sean independientes.
---
## Conclusión
Los arrays y objetos funcionan por referencia porque:
1. **Es más eficiente** en términos de memoria y rendimiento.
2. **Facilita la mutabilidad**, permitiendo que los cambios se reflejen automáticamente en todas las referencias.
3. **Es coherente** con el diseño de programación orientada a objetos.
4. **Sigue un estándar** que es consistente con otros lenguajes.
Aunque este comportamiento puede parecer confuso al principio, con el tiempo te darás cuenta de que es una decisión lógica y práctica para manejar datos complejos. Si necesitas una copia independiente, siempre puedes usar métodos como `slice()` o técnicas específicas para clonar objetos y arrays.
---
## 1. **Eficiencia en memoria y rendimiento**
Cuando trabajas con tipos complejos como arrays u objetos, estos pueden contener grandes cantidades de información. Si cada vez que los asignaras a una nueva variable se hiciera una copia completa de los datos, esto consumiría mucha memoria y sería muy lento.
Por ejemplo, considera este caso:
```actionscript
var arrayGrande = [1, 2, 3, ..., 100000]; // Un array con 100,000 elementos
var copia = arrayGrande; // ¿Qué pasaría si fuera una copia completa?
```
Si el lenguaje copiara todo el array al asignarlo, el programa tendría que:
1. Reservar **el doble** de espacio en memoria para almacenar los mismos datos.
2. Copiar cada uno de los 100,000 elementos al nuevo array.
Esto haría que las operaciones de asignación fueran lentas y que el uso de memoria se disparara rápidamente en aplicaciones que manejan muchos datos.
**Por referencia**, en cambio, el lenguaje simplemente crea un "puntero" o "referencia" al espacio de memoria donde ya está almacenado el array. Esto es mucho más rápido y eficiente porque no duplica los datos, sino que solo comparte la referencia.
---
## 2. **Facilita la mutabilidad**
Cuando trabajas con objetos y arrays, muchas veces necesitas que todos los cambios se reflejen en el mismo lugar. Si los arrays fueran siempre copiados al asignarlos, sería complicado coordinar los cambios entre diferentes partes de tu código.
Por ejemplo:
```actionscript
var config = { ancho: 800, alto: 600 };
var referencia = config;
referencia.ancho = 1024;
trace(config.ancho); // 1024
```
Aquí, tanto `config` como `referencia` apuntan al mismo objeto. Si cambias un valor en `referencia`, también se refleja en `config`, porque ambos son referencias al mismo objeto. Esto facilita que múltiples variables o funciones trabajen con los mismos datos sin necesidad de copiar y sincronizar los cambios manualmente.
Si los objetos fueran copiados automáticamente, el cambio en `referencia` no afectaría a `config`, y tendrías que buscar formas más complicadas de mantenerlos sincronizados.
---
## 3. **Es coherente con el diseño de programación orientada a objetos**
Los lenguajes como ActionScript están diseñados para manejar objetos de manera flexible. En este paradigma, los objetos y arrays suelen comportarse como entidades compartidas, **en lugar de duplicarse automáticamente**. Esto es clave para trabajar con estructuras de datos dinámicas, como listas enlazadas, árboles, o gráficos, donde las relaciones entre los elementos son importantes.
Por ejemplo:
```actionscript
var nodo1 = { valor: 1, siguiente: null };
var nodo2 = { valor: 2, siguiente: nodo1 };
trace(nodo2.siguiente.valor); // 1
```
Este tipo de estructuras serían mucho más difíciles de implementar si cada asignación hiciera copias completas de los datos.
---
## 4. **Consistencia con otros lenguajes**
ActionScript heredó muchas de sus características de javascript (que, a su vez, está inspirado en otros lenguajes como Java). En todos estos lenguajes, los objetos y arrays funcionan por referencia. Esto hace que el comportamiento sea predecible y **consistente con el estándar de la industria**, lo que facilita a los programadores aprender y trabajar con lenguajes similares.
---
## ¿Por qué no hacerlo todo por valor?
Si trabajar por referencia es tan eficiente, podrías preguntarte por qué no todos los tipos de datos funcionan así. La razón es que **los tipos primitivos (como números, cadenas y booleanos)** son mucho más simples y pequeños en términos de tamaño en memoria. Duplicarlos no es costoso y, en la mayoría de los casos, es más útil que sean independientes.
Por ejemplo:
```actionscript
var a = 5;
var b = a;
b = 10;
trace(a); // Todavía es 5
trace(b); // Es 10
```
En este caso, trabajar **por valor** tiene sentido porque los números son pequeñas cantidades de datos y se espera que sean independientes.
---
## Conclusión
Los arrays y objetos funcionan por referencia porque:
1. **Es más eficiente** en términos de memoria y rendimiento.
2. **Facilita la mutabilidad**, permitiendo que los cambios se reflejen automáticamente en todas las referencias.
3. **Es coherente** con el diseño de programación orientada a objetos.
4. **Sigue un estándar** que es consistente con otros lenguajes.
Aunque este comportamiento puede parecer confuso al principio, con el tiempo te darás cuenta de que es una decisión lógica y práctica para manejar datos complejos. Si necesitas una copia independiente, siempre puedes usar métodos como `slice()` o técnicas específicas para clonar objetos y arrays.
No le veo sentido, si quiero crear una copia debería poder hacerlo normalmente no con "slice", si consume mucho entonces el programador debería saberlo y no usarlo salvo que sea útil ¿por qué limitarnos?
Claro que no entendí todos los motivos que dice ahí, que una variable tenga 2 nombres puede ser útil pero... Si fuese así, debería poder hacerse con variables simples, y sobretodo debería poder hacerse de otro modo. Que una misma expresión, tan básica, haga cosas distintas según el tipo de variable parece absurdo.
¿Qué opinan?
Edit: Sabía que había excepciones a eso, tenemos por ejemplo que Número+Número es una suma pero si alguno de esos números es cadena entonces el + es concatenar. Pero vamos, no es lo mismo el + que el =. El = es sagrado xP
Edit2: Es como si al copiar un archivo en Windows, este en vez de eso copiara un acceso directo. Joder, si quiero una copia porque voy a modificar una, dejame copiar tranquilo