com.blackperl.Perl
Interface GrepBlock


public interface GrepBlock

Interface expected by methods in the Grep class. When using the grep function (see Grep), the data returned by the evaluation function has a flexible relationship to the data provided as input. While many uses of grep simply prune a list using boolean expressions, it is also possible to transform the data as well. Because of this, the interface method returns an object rather than a boolean value.

The grep function operates in one of two modes: testing and collating. When grep is collating results, those inputs for which the output is not null are added to the resulting list. When grep is "testing", each return value from eval must be an instance (or derivative) of Boolean. Those input elements for which the return value is "true" are added to the resulting list. This has the disadvantage that eval cannot return objects of type Boolean in collating mode.

One of the many ways in which Java and Perl differ functionally is that Java does not have support for the notion of "closures", or anonymous lexically-scoped blocks. Some aspects of this can be emulated using private or anonymous inner-classes. However, this is not a complete emulation, since these blocks can only access values from their enclosing scope that are marked static and final. This makes it a challenge to use this interface (or MapBlock) in the fashion most Perl developers are accustomed to.

The answer lies in extending the interface, or implementing it in an inner-class. Take for example the RegexpBlock inner-class from the Grep class:

     private final class RegexpBlock implements GrepBlock
     {
         private Pattern pat;
         
         protected RegexpBlock(final Pattern p)
         {
             pat = p;
         }
             
         public Object eval(final Object o)
         {
             return Boolean.valueOf(pat.matcher(o.toString()).matches());
         }
     }
 
This example implements only a single constructor which itself handles the initialization of the java.util.regex.Pattern instance variable pat. Then the eval method is defined as being in the testing mode (as defined earlier), in that it returns objects that are of the Boolean class. This implementation gets around the fact that an anonymous instance of GrepBlock created as part of a call to grep would not be able to refer to a specific pattern, unless it were visible to the current lexical scope as a final static value. As a fully-defined class, it is simple to add more member values and even accessors or other methods entirely. While this is still not the same as having true lexical closures, it will at least get the job done.

This interface may also be used in conjunction with the map function (see Map).


Method Summary
 java.lang.Object eval(java.lang.Object object)
          When the grep (or map) function is called with an object implementing this interface, this is the function it will expect to be able to invoke for each element in the list it also receives.
 

Method Detail

eval

public java.lang.Object eval(java.lang.Object object)
When the grep (or map) function is called with an object implementing this interface, this is the function it will expect to be able to invoke for each element in the list it also receives. The implementing class should provide this such that it takes a single argument, and returns a single object (or null, which is also acceptable).

Parameters:
object - An arbitrary object passed in by grep (or map)
Returns:
An arbitrary object, based on the functionality this method implements