No iba a publicar esto como respuesta, pero Xeoncross me lo pidió, así que aquí vamos:
(Nota al margen: si alguien pudiera solucionar el problema del descuento en el pequeño ejemplo de código, lo agradecería).
Erik Max Francis escribió:
"Brandon J. Van Every" escribió:
¿Qué hay de mejor en Ruby que en Python? Estoy seguro de que hay algo. ¿Qué es? ¿No tendría mucho más sentido preguntarle a la gente de Ruby esto, en lugar de a la gente de Python?
Podría, o no, dependiendo de los propósitos de uno: por ejemplo, si los propósitos de uno incluyen un "estudio sociológico" de la comunidad de Python, entonces hacer preguntas a esa comunidad probablemente resulte más revelador de información al respecto, que ponerlas en otro lugar :-). Personalmente, aproveché la oportunidad para seguir el tutorial de un día de Dave Thomas sobre Ruby en el último OSCON. Debajo de una delgada capa de diferencias de sintaxis, encuentro a Ruby y Python increíblemente similares: si calculara el árbol de expansión mínimo entre casi cualquier conjunto de idiomas, estoy bastante seguro de que Python y Ruby serían las dos primeras hojas en fusionarse un nodo intermedio :-).
Claro, me canso, en Ruby, de escribir el "final" tonto al final de cada bloque (en lugar de simplemente desangrar), pero luego evito escribir el igualmente tonto :
que Python requiere al
comienzo de cada bloque, así que eso es casi un lavado :-). Otras diferencias de sintaxis como @fooversus
self.fooo la mayor importancia del caso en Ruby vs Python son realmente tan irrelevantes para mí.
Otros sin duda basan su elección de lenguajes de programación en tales problemas, y generan los debates más candentes, pero para mí eso es solo un ejemplo de una de las Leyes de Parkinson en acción (la cantidad de debate sobre un tema es inversamente proporcional a la del tema importancia real). Una diferencia de sintaxis que considero importante, y a favor de Python, pero otras personas sin duda pensarán exactamente lo contrario, es "cómo se llama a una función que no toma parámetros". En Python (como en C), para llamar a una función siempre se aplica el "operador de llamada" - paréntesis finales justo después del objeto que está llamando (dentro de esos paréntesis finales van los argumentos que está pasando en la llamada, si no estás pasando argumentos, entonces los paréntesis están vacíos). Esto deja la mera mención de cualquier objeto, sin operador involucrado, que significa solo una referencia al objeto, en cualquier contexto, sin casos especiales, excepciones, reglas ad-hoc y similares. En Ruby (como en Pascal), para llamar a una función CON argumentos, pasa los argumentos (normalmente entre paréntesis, aunque ese no es siempre el caso) - PERO si la función no toma argumentos, simplemente menciona la función implícitamente. Esto puede cumplir con las expectativas de muchas personas (al menos, sin duda, aquellas cuya única experiencia previa de programación fue con Pascal u otros lenguajes con "llamadas implícitas" similares, como Visual Basic), pero para mí, significa la mera mención de un objeto puede significar ya sea una referencia al objeto, O una llamada al objeto, dependiendo del tipo de objeto, y en aquellos casos en los que no puedo obtener una referencia al objeto simplemente mencionándolo, necesitaré usar explícitamente "¡dame una referencia a esto, NO lo llames!" operadores que no son necesarios de otra manera. Siento que esto afecta la "primera clase" de funciones (o métodos u otros objetos invocables) y la posibilidad de intercambiar objetos sin problemas. Por lo tanto, para mí, esta diferencia de sintaxis específica es una marca negra seria contra Ruby, pero entiendo por qué los demás pensarían lo contrario, a pesar de que difícilmente podría estar en desacuerdo con ellos con más vehemencia :-). Debajo de la sintaxis, llegamos a algunas diferencias importantes en la semántica elemental, por ejemplo, las cadenas en Ruby son objetos mutables (como en C ++), mientras que en Python no son mutables (como en Java, o creo que C #). Una vez más, las personas que juzgan principalmente por lo que ya están familiarizados pueden pensar que esto es una ventaja para Ruby (a menos que estén familiarizados con Java o C #, por supuesto :-). Yo, creo que las cadenas inmutables son una excelente idea (y no me sorprende que Java, independientemente, creo, reinventó esa idea que ya estaba en Python), aunque tampoco me importaría tener un tipo de "buffer de cadena mutable" (e idealmente uno con mejor facilidad de uso que los propios "buffers de cadenas" de Java); y no doy este juicio por familiaridad, antes de estudiar Java, aparte de los lenguajes de programación funcionales donde las personas que juzgan principalmente por lo que ya están familiarizados pueden pensar que esto es una ventaja para Ruby (a menos que estén familiarizados con Java o C #, por supuesto :-). Yo, creo que las cadenas inmutables son una excelente idea (y no me sorprende que Java, independientemente, creo, reinventó esa idea que ya estaba en Python), aunque tampoco me importaría tener un tipo de "buffer de cadena mutable" (e idealmente uno con mejor facilidad de uso que los propios "buffers de cadenas" de Java); y no juzgo por familiaridad, antes de estudiar Java, aparte de los lenguajes de programación funcionales donde las personas que juzgan principalmente por lo que ya están familiarizados pueden pensar que esto es una ventaja para Ruby (a menos que estén familiarizados con Java o C #, por supuesto :-). Yo, creo que las cadenas inmutables son una excelente idea (y no me sorprende que Java, independientemente, creo, reinventó esa idea que ya estaba en Python), aunque tampoco me importaría tener un tipo de "buffer de cadena mutable" (e idealmente uno con mejor facilidad de uso que los propios "buffers de cadenas" de Java); y no juzgo por familiaridad, antes de estudiar Java, aparte de los lenguajes de programación funcionales donde Creo que las cadenas inmutables son una excelente idea (y no me sorprende que Java, independientemente, creo que reinventó esa idea que ya estaba en Python), aunque no me importaría tener un tipo de "buffer de cadena mutable" también (y idealmente uno con mejor facilidad de uso que los propios "buffers de cadena" de Java); y no juzgo por familiaridad, antes de estudiar Java, aparte de los lenguajes de programación funcionales donde Creo que las cadenas inmutables son una excelente idea (y no me sorprende que Java, independientemente, creo que reinventó esa idea que ya estaba en Python), aunque no me importaría tener un tipo de "buffer de cadena mutable" también (y idealmente uno con mejor facilidad de uso que los propios "buffers de cadena" de Java); y no doy este juicio por familiaridad, antes de estudiar Java, aparte de los lenguajes de programación funcionales dondetodos los datos son inmutables, todos los lenguajes que conocía tenían cadenas mutables; sin embargo, cuando vi por primera vez la idea de la cadena inmutable en Java (que aprendí mucho antes de aprender Python), inmediatamente me pareció excelente, una muy buena opción para la semántica de referencia de un lenguaje de programación de nivel superior (a diferencia de la semántica de valor que mejor se adapta a los lenguajes más cercanos a la máquina y más alejados de las aplicaciones, como C) con cadenas como una primera clase, incorporada (y bonita crucial) tipo de datos.
Ruby tiene algunas ventajas en la semántica elemental: por ejemplo, la eliminación de las "listas vs tuplas" de Python es una distinción extremadamente sutil. Pero sobre todo el puntaje (como lo mantengo, con simplicidad, una gran ventaja y distinciones sutiles e inteligentes, un notable menos) está en contra de Ruby (por ejemplo, tener intervalos cerrados y medio abiertos, con las anotaciones a..by a .. .b [alguien quiere afirmar que es obvio cuál es cuál? -)], es una tontería - ¡En mi humilde opinión, por supuesto!). Una vez más, las personas que consideran tener muchas cosas similares pero sutilmente diferentes en el núcleo de un idioma MÁS, en lugar de MENOS, por supuesto contarán esto "al revés" de la forma en que los cuento :-).
No se deje engañar por estas comparaciones para pensar que los dos idiomas son
muydiferente, te importa. No lo son Pero si me piden comparar "capelli d'angelo" con "spaghettini", después de señalar que estos dos tipos de pasta son casi indistinguibles para cualquiera e intercambiables en cualquier plato que desee preparar, entonces inevitablemente tendría para pasar al examen microscópico de cómo las longitudes y diámetros difieren imperceptiblemente, cómo se afilan los extremos de los hilos en un caso y no en el otro, y así sucesivamente, para tratar de explicar por qué yo personalmente preferiría capelli d 'angelo como la pasta en cualquier tipo de caldo, pero preferiría spaghettini como la pastasciutta para ir con salsas adecuadas para esas formas largas y delgadas de pasta (aceite de oliva, ajo picado, pimientos rojos picados y anchoas finamente molidas, por ejemplo, pero si rebanó los ajos y los pimientos en lugar de picarlos, entonces debe elegir el cuerpo de espagueti más sólido en lugar de la evanescencia más delgada de los espaguetis, y le recomendamos que renuncie a la vista y agregue un poco de albahaca fresca de primavera [ o incluso, soy un hereje ...! - hojas de menta clara - en el último momento antes de servir el plato). Vaya, lo siento, eso demuestra que estoy viajando al extranjero y no he comido pasta por un tiempo, supongo. ¡Pero la analogía sigue siendo bastante buena! -) y sería aconsejable renunciar a la vista y agregar un poco de albahaca fresca de primavera [o incluso, ¡soy un hereje ...! - hojas de menta clara - en el último momento antes de servir el plato). Vaya, lo siento, eso demuestra que estoy viajando al extranjero y no he comido pasta por un tiempo, supongo. ¡Pero la analogía sigue siendo bastante buena! -) y sería aconsejable renunciar a la vista y agregar un poco de albahaca fresca de primavera [o incluso, ¡soy un hereje ...! - hojas de menta clara - en el último momento antes de servir el plato). Vaya, lo siento, eso demuestra que estoy viajando al extranjero y no he comido pasta por un tiempo, supongo. ¡Pero la analogía sigue siendo bastante buena! -)
Entonces, volviendo a Python y Ruby, llegamos a los dos grandes (en términos de lenguaje apropiado: abandonar las bibliotecas y otros accesorios importantes como herramientas y entornos, cómo incrustar / extender cada idioma, etc., etc., fuera de por ahora, no se aplicarían a todas las IMPLEMENTACIONES de cada idioma de todos modos, por ejemplo, Jython vs Classic Python son dos implementaciones del lenguaje Python):
Los iteradores y bloques de código de Ruby frente a los iteradores y generadores de Python;
La "dinámica" desenfrenada TOTAL de Ruby, que incluye la capacidad de "reabrir" cualquier clase existente, incluidas todas las integradas, y cambiar su comportamiento en tiempo de ejecución, frente a la gran pero limitada
dinámica de Python , que nunca cambia el comportamiento de las clases existentes. clases integradas y sus instancias.
Personalmente, considero 1 un lavado (las diferencias son tan profundas que fácilmente podría ver a las personas odiando cualquiera de los dos enfoques y revertir el otro, pero en MIS escalas personales, las ventajas y desventajas casi se igualan); y [2] un tema crucial, uno que hace que Ruby sea mucho más adecuado para "retoques", PERO Python es igualmente más adecuado para su uso en grandes aplicaciones de producción. Es divertido, en cierto modo, porque ambos idiomas son MUCHO más dinámicos que la mayoría de los demás, que al final la diferencia clave entre ellos de mi POV debería depender de eso: que Ruby "va a once" en este sentido (la referencia aquí está a "Spinal Tap", por supuesto). En rubí¡PUEDO HACER ESO ! Es decir, puedo alterar dinámicamente la clase de cadena incorporada para que
a = "Hola mundo"
b = "hola mundo"
si a == b
imprimir "igual! \ n"
más
imprimir "diferente! \ n"
final
Imprimirá "igual". En python, NO hay forma de que pueda hacer eso. A los efectos de la metaprogramación, la implementación de marcos experimentales y similares, esta increíble capacidad dinámica de Ruby es extremadamente
atractivo. PERO, si estamos hablando de aplicaciones grandes, desarrolladas por muchas personas y mantenidas por más, incluyendo todo tipo de bibliotecas de diversas fuentes, y que necesitan entrar en producción en sitios de clientes ... bueno, no QUIERO Un lenguaje que es MUY dinámico, muchas gracias. Odio la idea de que una biblioteca rompa involuntariamente otras no relacionadas que confían en que esas cadenas son diferentes: ese es el tipo de "canal" profundo y profundamente oculto, entre piezas de código que MIRAN separadas y DEBEN SER separadas, que deletrean la muerte en programación a gran escala. Al permitir que cualquier módulo afecte el comportamiento de cualquier otro "encubierto",
Si tuviera que usar Ruby para una aplicación tan grande, trataría de confiar en restricciones de estilo de codificación, muchas pruebas (para volver a ejecutar cada vez que CUALQUIER cosa cambie, incluso lo que debería estar totalmente sin relación ...) y similares, para prohibir el uso de esta función de lenguaje. Pero NO tener la función en primer lugar es incluso mejor, en mi opinión, al igual que Python sería un lenguaje aún mejor para la programación de aplicaciones si se pudiera "concretar" cierto número de funciones integradas, por lo que SABÍA que , por ejemplo,
len("ciao")es 4 (en lugar de tener que preocuparse subliminalmente si alguien ha cambiado el enlace de nombre lenen el __builtins__
módulo ...). Espero que eventualmente Python "clave" sus elementos integrados.
Pero el problema es menor, ya que volver a vincular los elementos integrados es una práctica bastante obsoleta y poco común en Python. En Ruby, me parece importante, al igual que las
instalaciones macro demasiado potentes de otros idiomas (como, por ejemplo, Dylan) presentan riesgos similares en mi opinión (espero que Python nunca tenga un sistema macro tan poderoso, no importa el atractivo de "dejar que las personas definan sus propios pequeños lenguajes específicos de dominio integrados en el lenguaje mismo": en mi humilde opinión, perjudicaría la maravillosa utilidad de Python para la programación de aplicaciones, al presentar una "molestia atractiva" al aspirante a manipulador que acecha en el corazón de cada programador ...).
Alex