tutorial rails que ejemplos descargar curso caracteristicas ruby-on-rails ruby

que - Ruby on Rails: alias_method_chain, ¿qué es exactamente?



ruby on rails tutorial (4)

He intentado leer varias publicaciones de blog que intentan explicar alias_method_chain y las razones para usarlo y no usarlo. En particular, presté atención a:

http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain

y

http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/

Todavía no veo ningún uso práctico para alias_method_chain. ¿Alguien podría explicar algunas cosas?

1 - ¿Todavía se usa?
2 - ¿Cuándo usarías alias_method_chain y por qué?


¿se usa para nada?

Parece que sí . Es una práctica común entre los desarrolladores de Rails

¿Cuándo usarías alias_method_chain y por qué?

A pesar de las advertencias, alias_method_chain sigue siendo la principal estrategia utilizada cuando se inyecta la funcionalidad a un método existente, al menos en Rails 2.xy es seguido por muchas personas que lo amplían. Yehuda debería eliminar alias_method_chain de rails 3.0 para que diga de sus publicaciones y comentarios en las entradas de Rails. Todavía es utilizado por muchas extensiones que agregan un comportamiento personalizado en ciertos puntos de la ejecución, como registradores, reporteros de errores, evaluación comparativa, inyección de datos, etc.

OMI, la mejor alternativa es incluir un módulo, por lo que tiene decoración sobre delegación. (Por ejemplo, siga el ejemplo 4 en esta publicación ). De esta forma, puede modificar los objetos incluso individualmente si lo desea, sin contaminar los métodos de la clase. La desventaja de esto es que la cadena de búsqueda de métodos aumenta para cada módulo que se inyecta, pero de todos modos es de lo que se trata los módulos.

Una pregunta muy interesante, eche un vistazo a lo que otras personas piensan al respecto.


1 - ¿Todavía se usa?

Aparentemente sí, alias_method_chain() todavía se usa en Rails (a partir de la versión 3.0.0).

2 - ¿Cuándo usarías alias_method_chain y por qué?

( Nota: lo siguiente se basa principalmente en la discusión de alias_method_chain() en Metaprogramming Ruby por Paolo Perrotta, que es un excelente libro que debes tener en tus manos).

Comencemos con un ejemplo básico:

class Klass def salute puts "Aloha!" end end Klass.new.salute # => Aloha!

Ahora supongamos que queremos rodear a Klass#salute() con el comportamiento de registro. Podemos hacer eso que Perrotta llama un alias alrededor :

class Klass def salute_with_log puts "Calling method..." salute_without_log puts "...Method called" end alias_method :salute_without_log, :salute alias_method :salute, :salute_with_log end Klass.new.salute # Prints the following: # Calling method... # Aloha! # ...Method called

salute_with_log() un nuevo método llamado salute_with_log() y lo alias para salute() . El código que solía llamar a salute() todavía funciona, pero también obtiene el nuevo comportamiento de registro. También definimos un alias para el salute() original salute() , por lo que aún podemos saludar sin iniciar sesión:

Klass.new.salute_without_log # => Aloha!

Entonces, el salute() ahora se llama salute_without_log() . Si queremos iniciar sesión, podemos llamar a salute_with_log() o a salute() , que son alias del mismo método. ¿Confuso? ¡Bueno!

Según Perrotta, este tipo de alias es muy común en Rails:

Mira otro ejemplo de Rails resolviendo un problema a su manera. Hace algunas versiones, el código de Rails contenía muchas instancias de la misma expresión idiomática: se usaba Around Alias (155) para agregar una función a un método, y la versión anterior del método se method_without_feature() a algo como method_without_feature() . Además de los nombres de los métodos, que cambiaban cada vez, el código que hacía esto siempre era el mismo, duplicado por todos lados. En la mayoría de los idiomas, no puede evitar ese tipo de duplicación. En Ruby, puedes rociar un poco de metaprogramación mágica sobre tu patrón y extraerlo en su propio método ... y así nació alias_method_chain() .

En otras palabras, usted proporciona el método original, foo() , y el método mejorado, foo_with_feature() , y termina con tres métodos: foo() , foo_with_feature() y foo_without_feature() . Los primeros dos incluyen la función, mientras que el tercero no. En lugar de duplicar estos alias por todos alias_method_chain() , alias_method_chain() provisto por ActiveSupport hace todo el alias por usted.


No estoy seguro si ha pasado de moda con Rails 3 o no, pero todavía se usa activamente en versiones anteriores.

Se usa para inyectar alguna funcionalidad antes (o después) de llamar a un método, sin modificar ningún lugar que llame a ese método. Mira este ejemplo:

module SwitchableSmtp module InstanceMethods def deliver_with_switchable_smtp!(mail = @mail) unless logger.nil? logger.info "Switching SMTP server to: #{custom_smtp.inspect}" end ActionMailer::Base.smtp_settings = custom_smtp unless custom_smtp.nil? deliver_without_switchable_smtp!(mail = @mail) end end def self.included(receiver) receiver.send :include, InstanceMethods receiver.class_eval do alias_method_chain :deliver!, :switchable_smtp end end end

¡Es una adición a ActionMailer para permitir el intercambio de la configuración SMTP en cada llamada para deliver! . ¡Llamando alias_method_chain puedes definir un método deliver_with_switchable_smtp! en el que haces tus cosas personalizadas, y llama a deliver_without_switchable_smtp! a partir de ahí cuando hayas terminado.

alias_method_chain el viejo deliver! a su nuevo método personalizado, por lo que el resto de su aplicación ni siquiera sabe deliver! ahora también hace tus cosas personalizadas.