Ruby es interpretado. Las variables son referencias a datos, pero no los datos en sí. Esto facilita el uso de la misma variable para datos de diferentes tipos.
La asignación de lhs = rhs luego copia la referencia en la rhs, no los datos. Esto difiere en otros lenguajes, como C, donde la asignación hace una copia de datos a lhs de rhs.
Entonces, para la llamada a la función, la variable pasada, digamos x, se copia en una variable local en la función, pero x es una referencia. Luego habrá dos copias de la referencia, ambas haciendo referencia a los mismos datos. Uno estará en la persona que llama, uno en la función.
La asignación en la función luego copiaría una nueva referencia a la versión de la función de x. Después de esto, la versión de x de la persona que llama permanece sin cambios. Sigue siendo una referencia a los datos originales.
Por el contrario, usar el método .replace en x hará que ruby haga una copia de datos. Si se usa el reemplazo antes de cualquier nueva asignación, entonces la persona que llama verá el cambio de datos en su versión también.
Del mismo modo, siempre que la referencia original esté intacta para la variable pasada, las variables de instancia serán las mismas que ve la persona que llama. Dentro del marco de un objeto, las variables de instancia siempre tienen los valores de referencia más actualizados, ya sean proporcionados por el llamador o establecidos en la función a la que se pasó la clase.
La 'llamada por valor' o 'llamada por referencia' se confunde aquí debido a la confusión sobre '=' En idiomas compilados '=' es una copia de datos. Aquí en este lenguaje interpretado '=' hay una copia de referencia. En el ejemplo, se pasa la referencia seguida de una copia de referencia aunque '=' que identifica el original pasado como referencia, y luego las personas que hablan de ello como si '=' fuera una copia de datos.
Para ser coherente con las definiciones, debemos mantener '.replace', ya que es una copia de datos. Desde la perspectiva de '.replace' vemos que esto es realmente pasar por referencia. Además, si pasamos por el depurador, vemos que se pasan referencias, ya que las variables son referencias.
Sin embargo, si debemos mantener '=' como marco de referencia, entonces sí podemos ver los datos pasados hasta una asignación, y luego no podemos verlos más después de la asignación mientras los datos de la persona que llama permanecen sin cambios. A nivel de comportamiento, esto es pasar por valor siempre que no consideremos que el valor pasado sea compuesto, ya que no podremos mantener parte de él mientras cambiamos la otra parte en una sola asignación (como esa asignación cambia la referencia y el original queda fuera de alcance). También habrá una verruga, en ese caso, las variables en los objetos serán referencias, como lo son todas las variables. Por lo tanto, nos veremos obligados a hablar sobre pasar 'referencias por valor' y a usar locuciones relacionadas.