Selectors

< Transformers Executors >

What are selectors?

Selectors are qualifiers that have a filter function. They typically apply only to collection types and can be combined using logical operators. A selector specifies a condition that must be satisfied by an object to be included in the result collection. In theory, you could have a selector that creates a result collection containing more objects than the input collection. In practice, selectors always act as filters, i.e. they create a result collection that contains at most the input collection's elements, but usually fewer.

Take the following integer list as an example. Because we are only interested in the even integers we write:

C:\terp\bin>terp -e "{0,1,2,3,4,5,6,7,8}[even]"
02468

The resulting list had to be converted to a string for output purposes, so we ended up with a string concatenation of the even integers in the list. even is a built-in numeric selector, as is odd.

There are also comparison selectors that take one argument in addition to the implicit element to be tested. If you wish to select only elements greater than (gt) or less than (lt) a reference element, you can write:

C:\terp\bin>terp -e "{0,1,2,3,4,5,6,7,8}[gt(4) && lt(7)]"
56

The built-in comparison selectors are called lt (less than), le (less equal), eq (equal), ge (greater equal), gt (greater than), and ne (not equal). Each one takes one argument that has to be comparable to the elements in the collection.

Built-in selectors

The following table lists the built-in selectors that come with terp.

Built-in selectors
Name Arguments Description
dir none Selects File objects that are directories.
empty none Selects null or objects that convert to the empty string. (Most often used negated, as in !empty)
even none Selects numeric objects whose truncated integer representation is even.
eq Object Selects objects satisfying a == comparison to the given object.
executable none Selects File objects that are executable.
file none Selects File objects that are regular files.
ge Object Selects objects satisfying a >= comparison to the given object.
gt Object Selects objects satisfying a > comparison to the given object.
hidden none Selects File objects that are hidden.
jar none Selects File objects whose lowercased name ends with ".jar".
le Object Selects objects satisfying a <= comparison to the given object.
lt Object Selects objects satisfying a < comparison to the given object.
le Object Selects objects satisfying a <= comparison to the given object.
match String, Pattern Selects String objects that match the given pattern.
ne Object Selects objects satisfying a != comparison to the given object.
odd none Selects numeric objects whose truncated integer representation is odd.
readable none Selects File objects that are readable.
startswith String Selects String objects that start with the given string.
writable none Selects File objects that are writable.
zip none Selects File objects whose lowercased name ends with ".zip"..

Custom selectors

You can also build your own selectors by taking advantage of the automatically defined this variable. this always refers to the element that is currently being analyzed. If you wanted to select from a list of strings the ones that start with an 'a', you could write:

C:\terp\bin>terp -e "{'also','end','absolute'}[this.charAt(0)=='a']"
alsoabsolute

Custom selectors like the one above rely on one crucial assumption: it must be clear and obvious to the expression evaluation engine that the selector expression resolves to a boolean value.

In the above example, this is the case because the result of the == operator is guaranteed to be boolean. Simply calling a method that returns a boolean value is not good enough. You will have to use a logical or a comparison operator to make your intent clear. The reason for this lies in the dynamic nature of terp's expression evaluator. Lists and collections are not limited to elements of one type. A list might for example contain some string type elements and some other lists. A method that is declared to return a boolean value for one type of element might return a different value for another type of element. This is why we don't take method return types into account in the determination of whether an expression is boolean in nature or not.

So how can you make methods work in selectors? Take the example of invoking startsWith() on this. The String.startsWith() function returns a boolean value, so you might expect being able to use it directly in a selector expression. This is not the case. You will have to use a comparison to make it clear that your intent is selection and not formatting or transformation. You could for example write:

C:\terp\bin>terp -e "{'also','end','absolute'}[this.startsWith(\"a\")==true]"
alsoabsolute

 


Copyright 2006-2013 by Codemesh, Inc., ALL RIGHTS RESERVED

:
terp expressions
codemesh.com home expressions templates ant about us contact us download   

Commandline