This site contains older material on Eiffel. For the main Eiffel page, see http://www.eiffel.com.

To other EiffelShelf packages.

The Eiffel Shelf: Peter Horan' input filter

ISE note: we are pleased to make Peter Horan's input filter, one of the winning entry in the 1997 Class Struggle organized by the Nonprofit International Consortium for Eiffel, part of the Eiffel Shelf. As other Eiffel Shelf entries this is not an ISE product but the work of Peter, who is also the authors of the present introduction. Many thanks to him for contributing this award-winning class.

Class INPUT_FILTER: a general description

This class provides filter routines for accepting data from a user in certain domain and rejecting data outside that domain. Using a filter separates the filtering from the use of the data. Thus, the application requiring data input can specify the kind of input and leave it up to the filter to enforce this. That is, the filter allows the application to control the domain of the data before it is received.


                     .--------.  Requested kind of data .------.
  Arbitrary data --->| Filter |<------------------------| User |
                     |        |------------------------>|      |
                     .--------.  Only the right data    .------.

Alternatives to this approach are to accept all input and process it after the fact, or to use a parser to return a datum and its domain. This approach lies between the primitive post-hoc and sophisticated parser approaches.

A Shortcoming

In this version, the class is built using the features of STD_FILES. This has a shortcoming owing to the limited word size used for integers, and the absence (or perhaps my ignorance) of a means to detect overflow and underflow exceptions. This is because 'C' leaves that to the user, which means that one cannot know about such exceptions at the Eiffel end without handling the integer conversions oneself.

Features supplied

The feature last_input holds the most recent character accepted. The feature last_integer holds the most recent integer accepted.

Two routines for filtering integer data are supplied, "read_positive_integer" and "read_integer_between(lower, upper: INTEGER)". These ensure that last_integer >= 0 and lower <= last_integer <= upper respectively.

A routine for accepting input characters which are members of an argument string "read_input_in_string(s: STRING)" is also provided. Finally, the feature "message_expecting_yes_no(query: STRING): BOOLEAN is supplied. This is built using "read_input_in_string("YyNn")". The pattern here is a chain of filters, the first to restrict the character set to "YyNn" and the second to map the accepted character into a BOOLEAN.

Use of the rescue clause

If a numerical string is expected, starting it with non-numerical characters will cause readint to raise an exception. The rescue clause allows for this. There seems to be no other way in the circumstances to prevent the exception being raised.

Assessment and future extensions

Clearly the idea can be extended. I have used it in complex user interfaces where I wished to restrict the user to certain inputs. I have fould the pattern to be robust and easy to maintain. The purpose here is to examine what happens in an OO version of the pattern.

An obvious extension, not done because of time constraints, is to handle the integer conversion in the following way:

	read_integer_safely is
		local
			i: INTEGER
		do
			from
				read_input_in_string("0123456789 %T%N")
			until
				last_input = ' ' or
				last_input = '%T' or
				last_input = '%N'
			loop
				i := 10 * i + last_input.code - ('0').code
				read_input_in_string("0123456789 %T%N")
			end
			lastint := i
		end

Whether this should be in a supplier filter (playing the role of "io") or called internally will only be clear from implementation. Precisely how to handle overflow needs to be investigated.

However implemented, the pattern again is a chain of filters. The first restricts the allowed character set and the second builds the integer. A third such as "read_positive_integer" could follow, obtaining save input conversion for the application.

Author's address

    Peter Horan
    Email: peter@deakin.edu.au

To download the software

    Click here to download Peter's winning class struggle entry.

    You can also access the readme.txt file which contains the same class description as the present page.