Ejemplo: La Clase Filter

En este ejemplo - modificado de uno en el libro [3] - creamos una clase Filter que proveee un pequeño DSL para especificar restricciones que puedan ser usados sobre objetos Enumerable para filtrar los elementos producidos por el objeto Enumerable:
19 f =
20 f.constraint { |x| x > 10 } .and { |x| x.even? } .and { |x| x % 3 == 0 }
22 puts (8..24).select(&f)
Del uso del objeto Filter deducimos que los objetos Filter debe tener métodos
  1. constraint (línea 20)
  2. and (línea 20)
  3. Además por la forma de uso (línea 20) podemos ver que constraint devuelve un objeto Filter, lo mismo que and
  4. to_proc (línea 22)
La ejecución resulta en:
[~/srcLPP/rubytesting/ruby_best_practices/chapter5_functional_programming_techniques]$ ruby filter.rb 
Este es el código de la clase:
[~/srcLPP/rubytesting/ruby_best_practices/chapter5_functional_programming_techniques]$ cat -n filter.rb 
 1  class Filter
 2    def initialize
 3      @constraints = []
 4    end
 6    def constraint(&block)
 7      @constraints << block
 8      self
 9    end
10    alias and constraint
12    def to_proc
13      ->(e) { @constraints.all? { |fn| fn[e] } }
14    end
16  end

  1. Method chaining, is a common syntax for invoking multiple method calls in object-oriented programming languages."Peter").age(21).introduce

  2. Each method returns an object, allowing the calls to be chained together in a single statement.

  3. Chaining is syntactic sugar which eliminates the need for intermediate variables.

  4. A similar syntax is method cascading, where after the method call the expression evaluates to the current object, not the natural return value of the method.

  5. Cascading can be implemented using method chaining by having the method return the current object itself (self).

  6. Cascading is a key technique in fluent interfaces, and since chaining is widely implemented in object-oriented languages while cascading isn't, this form of cascading-by-chaining by returning self is often referred to simply as chaining.

  7. Both chaining and cascading come from the Smalltalk language.

  8. The call @constraints.all? { |fn| fn[e] } passes each element of the collection @constraints to the given block. The method returns true if the block never returns false or nil.


  1. FluentInterface. Martin Fowler. 20 December 2005

Casiano Rodriguez León 2015-01-07