2011-04-21 15 views
19

Algunos lenguajes como Ruby y JavaScript tienen clases abiertas que le permiten modificar interfaces incluso de clases principales como números, cadenas, matrices, etc. Obviamente, hacerlo podría confundir a otros que están familiarizados con la API, pero ¿hay alguna buena razón para evitarlo? de lo contrario, suponiendo que está agregando a la interfaz y no está cambiando el comportamiento existente?¿Es realmente tan malo el "parche de mono"?

Por ejemplo, podría ser bueno agregar una implementación de Array.map a los navegadores web que no implementen la 5ª edición de ECMAScript (y si no necesita todo jQuery). O bien, sus matrices de Ruby podrían beneficiarse de un método de conveniencia "suma" que utiliza "inyectar". Siempre que los cambios estén aislados en sus sistemas (por ejemplo, no forma parte de un paquete de software que libera para su distribución) ¿hay alguna buena razón para no aprovechar esta función de idioma?

+1

FWIW, Hay una propuesta para incluir algo llamado "refinamientos" en Ruby 2.0 que mitigaría las trampas asociadas con el parche de monos. Solo google para "refinamientos de ruby", hay un par de artículos alrededor. –

+0

[¿El mono parcheando el mal?] (Http://www.singhajit.com/is-ruby-monkey-patching-evil) –

Respuesta

16

Wikipedia tiene un breve resumen de las trampas de la mono-parches:

http://en.wikipedia.org/wiki/Monkey_patch#Pitfalls

Hay un tiempo y lugar para todo, también para el mono-aplicación de parches. Los desarrolladores experimentados tienen muchas técnicas en sus manos y aprenden cuándo usarlas. Pocas veces es una técnica en sí misma lo que es "malo", solo uso desconsiderado de ella.

+1

eh, es una de esas cosas "si todos hicieran eso", como tirar basura en el highway –

+0

"Los desarrolladores con experiencia tienen muchas técnicas bajo la manga y saben cuándo usarlas" <- No estoy seguro de que haya alguna vez "un lugar y un lugar para el parche de monos". ¿Cuándo es mejor que pasar la variable como argumento, por ejemplo? – weberc2

+0

@ weberc2 Un buen ejemplo de parche de mono es un punto de referencia de la función lib de terceros. Agregar temporizador que se inicia antes de la ejecución de la función y termina después. Por qué no? –

3

Mientras se aíslan los cambios a sus sistemas (por ejemplo, que no forma parte de un paquete de software soltar para distribución) no es una buena razón no tomar ventaja de esta característica del lenguaje ?

Como desarrollador solitario en un problema aislado, no hay problemas para extender o alterar objetos nativos. También en proyectos más grandes, esta es una elección de equipo que debe hacerse.

Personalmente no me gusta tener objetos nativos en javascript alterado, pero es una práctica común y es una elección válida para hacer. Si vas a escribir una biblioteca o un código que debe ser usado por otros, lo evitaría en gran medida.

Sin embargo, es una opción de diseño válida para permitir al usuario establecer un indicador de configuración que indique sobrescribir objetos nativos con sus métodos de conveniencia porque es muy conveniente.

Para ilustrar un error específico de JavaScript.

Array.protoype.map = function map() { ... }; 

var a = [2]; 
for (var k in a) { 
    console.log(a[k]); 
} 
// 2, function map() { ... } 

Este problema se puede evitar mediante el uso de ES5 que permite que se inyecte propiedades no enumerables en un objeto.

Esto es principalmente una opción de diseño de alto nivel y todos deben tener en cuenta/estar de acuerdo con esto.

+0

'for ... in' with Array expression – user422039

+2

@ user422039 Sí, es un error ejemplar. Si es una buena práctica llamar a 'for in' en array es un problema diferente. – Raynos

+3

no, aquí usar la enumeración de propiedad para caminar array es el mayor problema – user422039

2

Es perfectamente razonable utilizar el "parche de monos" para corregir un problema específico conocido donde la alternativa sería esperar a que un parche lo arregle. Eso significa asumir temporalmente la responsabilidad de arreglar algo hasta que haya una solución "adecuada" y formalmente lanzada que pueda implementar.

Una opinión considerada por Gilad Bracha en mono Parches: http://gbracha.blogspot.com/2008/03/monkey-patching.html

22

mono-aplicación de parches, al igual que muchas herramientas en la caja de herramientas de programación, se puede utilizar tanto para el bien como para el mal. La pregunta es dónde, en general, tales herramientas tienden a ser las más utilizadas. En mi experiencia con Ruby, el equilibrio pesa mucho en el lado "malvado".

Entonces, ¿qué es un "mal" uso de parche de mono? Bueno, el parche de monos en general te deja abierto a grandes enfrentamientos potencialmente no diagnosticables. Tengo una clase A. Tengo algún tipo de módulo de reparación de monos MB que parches A para incluir method1, method2 y method3. Tengo otro módulo de reparación de mono MC que también parches A para incluir un method2, method3 y . Ahora estoy en un aprieto Llamo al instance_of_A.method2: ¿de quién se llama el método? La respuesta a eso puede depender de muchos factores:

  1. ¿En qué orden introduje los módulos de parcheo?
  2. ¿Los parches se aplican inmediatamente o en algún tipo de circunstancia condicional?
  3. AAAAAAARGH! ¡LAS ARAÑAS ESTÁN COMIENDO MI PELOTA DE OJO DESDE EL INTERIOR!

OK, por lo que # 3 es tal vez un poco demasiado melodramática ....

De todos modos, ese es el problema con el mono de parches: problemas en pugna horribles. Dada la naturaleza altamente dinámica de los lenguajes que generalmente lo respaldan, ya enfrenta muchos problemas potenciales de "acción espeluznante a distancia"; el parche de monos simplemente se suma a estos.

Tener parches para monos disponibles es bueno si eres un desarrollador responsable. Desafortunadamente, IME, lo que tiende a suceder es que alguien vea parches de mono y dice: "¡Dulce! Voy a aplicar un parche en lugar de verificar si otros mecanismos pueden no ser más apropiados". Esta es una situación más o menos análoga a las bases de código Lisp creadas por personas que buscan macros antes de que piensen simplemente hacerlo como una función.

+0

Tengo más curiosidad acerca de cuándo se puede usar para bien. El lado malo de la moneda es obvio, pero ¿cuándo es realmente más útil que cambiar tu programa para aceptar cualquier cosa que estés parcheando como argumento? Quiero decir, tenemos estos patrones arquitectónicos y parece que cosas como el parche de monos existen solo para subvertirlos por el bien de la subversión. – weberc2

0

Las condiciones que describe (agregar o no cambiar el comportamiento existente y no divulgar el código al mundo exterior) parecen relativamente seguras. Sin embargo, podrían surgir problemas si la próxima versión de Ruby o JavaScript o Rails cambia su API. Por ejemplo, ¿qué pasa si alguna versión futura de jQuery comprueba si Array.map ya está definido, y asume que es la versión de mapa EMCA5Script cuando en realidad es su parche de mono?

Del mismo modo, qué ocurre si defines "sum" en Ruby, y un día decides que quieres usar ese código ruby ​​en Rails o añades la joya Active Support a tu proyecto. El Soporte activo también define un método de suma (en Enumerable), por lo que hay un choque.

+0

"¿Qué pasa si alguna versión futura de jQuery comprueba si Array.map ya está definido y asume que es la versión del mapa EMCA5Script?" Luego hizo una suposición injustificada y merece lo que obtiene. – ChrisJJ

Cuestiones relacionadas