¿Son: los símbolos en Ruby una abstracción permeable?

Estoy de acuerdo con Xuan, el uso de símbolos en Ruby proporciona una mejora en el rendimiento (la mayoría de las veces). Hay casos en los que el uso excesivo de símbolos puede provocar una pérdida real de memoria, lo cual no creo que quiera decir, pero no estoy seguro, así que abordaré eso primero:

Hablando de la pérdida de memoria:

Supongamos que tiene una fuente constante de información nueva, y cada registro está codificado por un nombre único. Luego, en su aplicación, lee dichos registros periódicamente y los coloca en un mapa de Hash con la clave de la versión del símbolo del nombre. Te das cuenta de que no puedes seguir haciendo esto para siempre, así que de vez en cuando caducas las entradas antiguas.
Si tiene un proceso Ruby ejecutando Rails que es muy longevo, entonces esto es un problema, incluso cuando expira las entradas del Mapa, los símbolos se quedarán en la memoria de tiempo de ejecución. Esto podría suceder, por ejemplo, si está ejecutando Rails en una aplicación independiente, o incluso a través de Phusion o algo con una configuración grande para el número máximo de solicitudes hasta el vencimiento.

Otro ejemplo simple: un método ruby ​​crea un millón de enteros aleatorios para algunos cálculos, y utiliza el formato de símbolo de esos enteros como claves hash. Incluso cuando el mapa hash obtiene basura recolectada, los símbolos no lo harán.

Así que sí, tenga cuidado de no usar en exceso instancias de símbolos.

Hablando de la fuga de abstracción:

1. Muchos idiomas tienen el mismo concepto (es decir, símbolos en Scala), para el mismo razonamiento de rendimiento.

2. Entonces, ¿qué pasa si el tipo es diferente? Ruby es dinámico y el tipo funciona bien con String, entonces, ¿cuál es el problema? En la mayoría de los casos, puede tratarlo como una cadena de todos modos, o realizar una llamada trivial to_s en él. El rendimiento puede diferir ligeramente, pero la funcionalidad es muy similar.

3. Depende de usted. Como dijo Miguel, este comportamiento no es involuntario o indeseable, y está bien documentado. Por lo tanto, no “con fugas”.

-Tom

Creo que los símbolos en Ruby (o en Lisps) no son una abstracción permeable porque el hecho de que están siendo internados es intencionalmente visible para el programador.

“Fuga” significa que la característica se filtra involuntaria e indeseablemente, como en ¿Cuáles son buenos ejemplos de abstracciones con fugas en la arquitectura de software?

Como probablemente ya sepa, el propósito de la pasantía es que las comparaciones puedan ser rápidas. Comparar dos cadenas para la igualdad lleva tiempo lineal (debe iterar sobre los caracteres). La comparación de dos símbolos para la igualdad lleva tiempo constante (ya que la identidad del objeto es igualdad).

Uno de los grandes usos de los símbolos en Ruby es para los nombres de los métodos. El método de send , que se utiliza para llamar dinámicamente un método, toma el nombre como símbolo. (Incluso cuando escribe una llamada a un método con el nombre directamente, el compilador lo trata esencialmente como una llamada para send , con el nombre como un símbolo). Y los métodos para cada clase se almacenan internamente en una tabla marcada por símbolos, en lugar de por instrumentos de cuerda. Cuando realiza una llamada a un método, todo lo que necesita hacer es buscar el método utilizando la comparación de símbolos, en lugar de una comparación de cadenas más lenta. Dado que la llamada a métodos es una operación común (es prácticamente todo lo que hace en el lenguaje), esta optimización es muy beneficiosa.

Ruby heredó estas cosas de Smalltalk, la mayoría de las implementaciones de las cuales también usan símbolos para llamar dinámicamente métodos.

Y no es necesariamente “permeable”. No sé cómo se hace en Ruby, pero en teoría, es posible que la tabla interna tenga una referencia débil al símbolo, de modo que si el símbolo ya no se usa en ninguna parte, se elimina de la tabla interna.