Honestamente, solía usar la primera forma (reapertura de la clase), ya que se siente más natural, pero su pregunta me obligó a investigar sobre el tema y aquí está el resultado.
El problema con la reapertura de la clase es que definirá silenciosamente una nueva clase si la original, que tenía la intención de reabrir, por alguna razón no estaba definida en este momento. El resultado podría ser diferente:
Si no se sobreescribe cualquier método, pero solo agregue las nuevas y se define la aplicación original (por ejemplo, archivo, donde la clase se define inicialmente es cargado) luego todo irá estar bien
Si redefine algunos métodos y el original se carga más tarde, sus métodos se redefinirán con sus versiones originales.
El caso más interesante es cuando se usa el estándar autoloading o algún mecanismo de recarga elegante (como el utilizado en Rails) para cargar/recargar clases. Algunas de estas soluciones se basan en const_missing que se invoca cuando hace referencia a una constante no definida. En ese caso, el mecanismo de carga automática intenta encontrar una definición de clase indefinida y cargarla. Pero si está definiendo clases por su cuenta (aunque tenía la intención de reabrir el ya definido), ya no 'desaparecerá' y el original nunca se cargará del todo ya que el mecanismo de carga automática no se activará.
Por otro lado, si se utiliza class_eval
Se le notificará al instante si la clase no se define por el momento. Además, como hace referencia a la clase cuando llama al método class_eval
, cualquier mecanismo de carga automática tendrá la posibilidad de localizar la definición de la clase y cargarla.
Teniendo esto en mente class_eval
parece ser un mejor enfoque. Sin embargo, me gustaría escuchar alguna otra opinión.
Posible duplicado de [parches mono vs clase \ _eval?] (Http://stackoverflow.com/questions/9399358/monkey-patching-vs-class-eval) – akostadinov