2011-08-23 12 views
8

Actualmente estoy experimentando con Ruby and Rails, y he accedido a algunas secciones en tutoriales y libros sobre metaprogramación. Muchos mencionan que es un componente esencial de Ruby, pero en realidad no entran en detalles. Es como si la metaprogramación fuera la última frontera para los programadores de Ruby. Procedente de un fondo .NET me cuesta entender por qué supuestamente es tan útil.¿Por qué es importante aprender sobre la metaprogramación y las clases propias en Ruby?

  • ¿Qué ventajas se obtienen al usar la metaprogramación?
  • ¿Qué es una clase de origen y cómo es diferente de un singleton?
  • ¿En qué situaciones es común el uso de la metaprogramación?
  • ¿Qué implicaciones éticas existen al usar código para modificar el comportamiento de otro código, especialmente el código que no es el suyo?

Respuesta

16
  • ¿Qué beneficios se obtuvieron al utilizar metaprogramming?

    Puede crear APIs más expresivos que sin ella (por ejemplo ActiveRecord utiliza metaprogramming para definir métodos de acceso basados ​​en nombres de columna de una tabla, para que pueda escribir cosas como person.age en lugar de algo así como person.read_attribute("age"), donde person es un objeto registro activo y la tabla people tiene una columna llamada age) y puede lograr algunas cosas con mucho menos código del que lo haría de otra manera.

  • ¿Qué es una clase de origen y cómo es diferente de un singleton?

    Los términos "clase propia" y "clase singleton" se usan indistintamente en el contexto de ruby.

  • ¿En qué situaciones se usa la metaprogramación?

    En situaciones en las que de lo contrario tendrías mucho código de placa de caldera o al crear DSL.

    Ejemplo de caso de uso 1:

    En lugar de escribir algo de código caldera de la placa de esta manera:

    class Foo 
        def bar 
        @bar 
        end 
    
        def bar=(b) 
        @bar = b 
        end 
    
        def baz 
        @baz 
        end 
    
        def baz=(b) 
        @baz = b 
        end 
    end 
    

    Usted puede escribir el código mucho más corto usando el método metaprogramming attr_accessor, que define automáticamente getter y métodos setter con nombres basados ​​en los argumentos que se dan:

    class Foo 
        attr_accessor :foo, :bar 
    end 
    

    Si attr_accessor no ALR eady existe en la biblioteca estándar, se podría definir por sí mismo como esto (para darle una idea de lo metaprogramming en rubí parece):

    class Module 
        def attr_accessor(*variable_names) 
        variable_names.each do |variable_name| 
         define_method(variable_name) do 
         instance_variable_get("@#{ variable_name }") 
         end 
    
         define_method("#{ variable_name }=") do |value| 
         instance_variable_set("@#{ variable_name }", value) 
         end 
        end 
        end 
    

    final

  • ¿Qué implicaciones éticas están allí alrededor de usar código para modificar el comportamiento de otro código, especialmente el código que no es el suyo?

    Ninguno.

+1

+1 Me gusta mucho el ejemplo 'attr_accessor', ya que muestra una ventaja importante de las sólidas capacidades de metaprogramación: la metaprogramación mantiene el lenguaje en sí mismo simple. 'attr_accessor' podría ser fácilmente una construcción de lenguaje separada en otro idioma (relacionado: propiedades en C#, etc.). En Ruby, es simplemente otro método. –

+0

Buena respuesta. Si bien es cierto que la clase eigenclass y singleton significan lo mismo en Ruby, este último es ahora el término preferido, como lo indica la existencia de los métodos 'singleton_class',' singleton_methods' y 'define_singleton_method'. –

4

Hay un momento y lugar para la metaprogramación. Creo que se menciona mucho en los libros de Ruby porque a la gente le gusta presumir de lo que Ruby puede hacer que otros idiomas no pueden hacer tan bien.

La metaprogramación es como no saber la palabra japonesa para "hamburguesa" o "sopa de fideos", pero conociendo a los japoneses para "éste por favor" ("kore o kudasai"), y poder señalar el artículo en el menú. Permite más flexibilidad, pero necesita más contexto para saber exactamente qué se está haciendo.

Si está creando ActiveRecord, que le permite hacer find_by_foo, la metaprogramación tiene sentido.

Si está escribiendo una biblioteca de pruebas de mutaciones, como zombie-chaser, o una aplicación de prueba de caracterización que prueba diferentes implementaciones de Ruby, como el Small Eigen Collider, la metaprogramación tiene sentido.

Sin embargo, si está escribiendo una aplicación, entonces generalmente no debería metaprogramar, sino simplemente programar. Por ejemplo, si está usando instance_variable_set en su aplicación, es más un olor a código que una indicación de qué tan competente es.

Las preguntas relacionadas es posible que desee leer incluyen https://stackoverflow.com/questions/1236191/what-will-i-learn-from-metaprogramming-ruby y Ruby metaprogramming online tutorial y Metaprogramming how much is too much?.

Realmente recomiendo el libro "Metaprogramación Ruby", porque no solo enseña metaprogramación, sino cómo funciona Ruby.

+0

+1 para el ejemplo japonés. ¡Simplemente perfecto! – rubish

Cuestiones relacionadas