NAME

Term::Interact - Interactively Get Validated Data

SYNOPSIS

  use Term::Interact;
  my $ti = Term::Interact->new( @args );
  # get validated data interactively
  $validated_data = $ti->get( @args );
  # check existing data non-interactively
  die "Invalid!" unless $ti->validate( $data, @args );

DESCRIPTION

Term::Interact enables you to interactively get validated data from a user. This is accomplished via a simple API, wherein you specify various parameters for prompting the user, as well as "checks" with which gotten data will be validated.

EXAMPLES

 # set up object with some optional parameters
 my $ti = Term::Interact->new(
   # set desired date formatting behavior
   # (See perldoc Date::Manip for syntax)
   date_format_display  =>  '%d-%b-%Y',
   date_format_return   =>  '%s',
   # database handle (see perldoc DBI) to
   # allow sql_checks.
   dbh  =>  $dbh,
 );
 my $num1 = $ti->get(
   msg        =>  'Enter a single digit number.',
   prompt     =>  'Go ahead, make my day: ',
   re_prompt  =>  'Try Again Here: ',
   check      =>  [
                    qr/^\d$/,
                    '%s is not a single digit number!'
                  ],
 );
 #
 # Resulting Interaction looks like:
 #
 # Enter a single digit number.
 #    Go ahead, make my day: w
 #    'w' is not a single digit number!
 #    Try Again Here: 23
 #    '23' is not a single digit number!
 #    Try Again Here: 2
 my $date = $ti->get (
   type     =>  'date',
   name     =>  'Date from 2001',
   confirm  =>  1,
   check    =>  [
                  ['<= 12-31-2001', '%s is not %s.'],
                  ['>= 01/01/2001', '%s is not %s.'],
                ]
 );
 #
 # Resulting Interaction looks like:
 #
 # Date from 2001: Enter a value.
 #    > 2002-03-12
 #    You entered: '12-Mar-2002'. Is this correct? (Y|n)
 #    '12-Mar-2002' is not <= 31-Dec-2001.
 #    > foo
 #    'foo' is not a valid date
 #    > 2000-12-31
 #    You entered: '31-Dec-2000'. Is this correct? (Y|n)
 #    '31-Dec-2000' is not >= 01/01/2001.
 #    > 2001-02-13
 #    You entered: '13-Feb-2001'. Is this correct? (Y|n)
 my $states_aref = $ti->get (
   msg        =>  'Please enter a comma delimited list of states.',
   prompt     =>  'State: ',
   re_prompt  =>  'Try Again: ',
   delimiter  =>  ',',
   case       =>  'uc',
   dbh        =>  $dbh,
   check      =>  [
                    'SELECT state FROM states ORDER BY state',
                    '%s is not a valid state code.  Valid codes are: %s'
                  ],
 );
 #
 # Resulting Interaction looks like:
 #
 # Please enter a comma delimited list of states.
 #    State: FOO
 #    'FOO' is not a valid state code.  Valid codes are: AA, AB, AE, AK,
 #    AL, AP, AQ, AR, AS, AZ, BC, CA, CO, CT, CZ, DC, DE, FL, FM, GA, GU,
 #    HI, IA, ID, IL, IN, KS, KY, LA, LB, MA, MB, MD, ME, MH, MI, MN, MO,
 #    MP, MS, MT, NB, NC, ND, NE, NF, NH, NJ, NM, NS, NT, NV, NY, OH, OK,
 #    ON, OR, PA, PE, PQ, PR, PW, RI, RM, SC, SD, SK, TN, TT, TX, UT, VA,
 #    VI, VT, WA, WI, WV, WY, YT
 #    Try Again: az, pa
 my $num2 = $ti->get (
   name   =>  'Number Less Than 10 and More than 3',
   check  =>  [
                [' < 10', '%s is not less than 10.'],
                ['>3', '%s is not %s.'],
              ]
 );
 #
 # Resulting Interaction looks like:
 #
 # Number Less Than 10 and More than 3: Enter a value.
 #    > f
 #    'f' is not numeric.
 #    > 1
 #    '1' is not > 3.
 #    > -1
 #    '-1' is not > 3.
 #    > 14
 #    '14' is not less than 10.
 #    > 5
 my $grades = $ti->get (
   name       =>  'Letter grade',
   delimiter  =>  ',',
   check      =>  [ 'A', 'B', 'C', 'D', 'F' ],
 );
 #
 # Resulting Interaction looks like:
 #
 # Letter grade: Enter a value or list of values delimited with commas.
 #    > 1
 #    > s
 #    > X
 #    > a, b
 #    > A, B, C
 # If multiple checks are specified, the ordering
 # is preserved.  In the example below, the sql_check
 # will be applied before the regex_check.
 my $foo = $ti->get (
   name       =>  $name,
   delimiter  =>  $delim,
   check      =>  [ 'SELECT foo FROM bar', qr/aaa|bbb|ccc/ ],
 );
 # multiple requests in one call to get method
 my ($foo, $bar) = $ti->get (
   [
     [
       name   =>  'foo',
       check  =>  [qw/ A B C /],
     ],
     # you can use an href if you prefer
     {
       name       =>  'bar',
       delimiter  =>  ',',
       check      =>  qr/kermit|der|frosch/,
     },
   ]
 );

METHODS

new

The new method constructs a Term::Interact object using default values and passed in key=>value parameters (see PARAMETERS section below). The parameter values stored in the object are subsequently accessible for reading and setting via methods named the same as the parameters. For example:

    # get the value of the date_format_return parameter
    my $fmt = $ti->date_format_return;
    # set the value of the date_format_return parameter
    # to DD-Mon-YYYY
    $ti->date_format_return( '%d-%b-%Y' );
get
The get method prompts the user for data and, if a check parameter (see check in the PARAMETERS section below) has been passed in, invokes the validate method to validate the user-provided data.
validate
The validate method accepts the data to be validated as its first parameter, and then the same key=>value parameters that new and get accept. One of these parameters needs to be the check parameter so that validation can be performed.
new_check
The new_check method uses a check parameter value to construct one or more check objects (which are returned in an aref). You'll not usually invoke this method, because the validate method transparently invokes it to transform its check parameter value into a collection of check objects. (These check objects are what the internal check methods actually use to validate data.) Nonetheless, you may invoke this method if you like. By doing so you could initially set the check parameter to an aref of check objects when invoking get or validate.
parameters

The parameters method returns information about available parameters. If called with no args, it will return a list of available parameter names in list context, or an href of all parameter information in scalar context: { interact => {type => 'bool', default => 1 }, name => {type => 'str', } , ... check => {type => ['str','aref','qr//','coderef'], } }

If called with a specific type, ala $ti->parameter(type => 'bool'), a list of parameters matching that type will be returned in list context, or an aref of parameter_name => type pairs will be returnes in scalar context. Also note that not-types are available, ala $ti->parameter(type => '!bool').

If called with the key value pair (default => 1), the method will return a list of parameters that have default values. If called this way in scalar context, the method will return an aref of parameter_name => default_value key value pairs.

All of the parameters are listed below in the PARAMETER section, and are all accessible via self-named mutator/accessor mehods.

PARAMETERS

These parameters are available for use with new, where they will be stored within the constructed object. They are also available for use with the get and validate methods, where they will override any values stored in the object, but only for the duration of that method call. In other words, the parameter values stored in the object during construction will be temporarilly overriden, but not changed by, any variant parameter values subsequently supplied to get or validate. The parameter values stored in the object may be changed, however, by invoking the self-named method accessor/mutators, ala $ti->timeout( 30 ).

interact
bool: Defaults to 1, of course, but you may turn interact mode off. In that case the validate method works as normal, but the get method will simply return the default value (or die if none is set).
name
str: Used in auto-assembling a message for the user if no msg parameter was specified.
type
str: Currently, the only meaningful value for this parameter is 'date'. If set to date, all input from the user and all check values supplied by the programmer will be parsed as dates by Date::Manip.
allow_null
bool: Defaults to 0. Set to 1 to allow user to enter 'NULL', regardless of any other checking. This is useful for database related prompting.
timeout
num: Defaults to 600 seconds. Set to 0 to turn off the timeout functionality. Timeout results in a fatal error which you may catch as you like. (The timeout parameter will be ignored under MS Windows, where its functionality is not possible.)
maxtries
num: Defaults to 20. Set to 0 turn off the maxtries functionality. Exceeding the maxtries results in a fatal error which you may catch as you like.
shared_autoformat_args
href: Defaults to {all => 1, fill => 0, right => [ the value of term_width ]}. The autoformat method from Text::Autoformat is used to format everything printed to FH_OUT. This href will be passed to autoformat every time it is invoked.
menu
str: Menu that will print prior to msg. No formatting will be performed on the menu. No menu will be printed unless this value is set.
msg
str: Message that will print prior to user input prompt. No msg will be printed if defined as 0. If left undefined, a message will be auto-generated based on other parameter values.
succinct
bool: Defaults to 0. If set to 1: If a parm name was given, it will be used as a msg. Otherwise the msg will be set to ''. If a default value was provided, the default prompt will be '[default_value]> ' instead of the normal default prompt.
msg_indent
num: Defaults to 0. Number of spaces that message will be indented from the terminal's left margin when output to FH_OUT.
msg_newline
num: Defaults to 1. The number of newlines prepended to msg when it is printed to FH_OUT.
prompt
str: Defaults to '> '. User will be prompted for input with this string.
reprompt
str: User will be re-prompted for input (as necessary) with this string. If not set, the value of prompt will be used instead.
prompt_indent
num: Defaults to 4. Number of spaces that all prompts will be indented from the terminal's left margin when output to FH_OUT.
case
str: If specified, the case of user input will be adjusted prior to validation. The uc, lc, and ucfirst operators may be specified.
confirm
bool: Defaults to 0. The user will be prompted to confirm the input if set to 1.
echo
bool: Defaults to 0. If set to 1, the get method will echo the user's validated choice to FH_OUT just prior to returning.
echo_quote
str: Defaults to "'" (a single quote). Whenever user input is echoed to the terminal, it will be quoted with whatever character string is found here, if any.
delimiter
str: Set this parameter to allow the user to enter multiple values via delimitation. Note this is a string value, not a pattern.
delimiter_spacing
bool: Defaults to 1, allowing user to add whitespace to either or both sides of the delimiter when entering a list of values. Whitespace before and after any delimiters will then be discarded when reading user input.
min_elem
num: Set this parameter to require the user to enter a minimum number of values. Note this is a meaningful parameter only when used in conjunction with delimiter.
max_elem
num: Set this parameter to restrict the user to a maximum number of values they can enter. Note this is a meaningful parameter only when used in conjunction with delimiter.
unique_elem
bool: Set this parameter to require all elements of the user-entered delimited value list to be unique. Note this is a meaningful parameter only when used in conjunction with delimiter.
default
str or aref: If the user is permitted to input multiple values (i.e., you have specified a delimiter), you may specify multiple default values by passing them in an aref. In any case you may pass in one default value as a string.
check_default
bool: Defaults to 0. If the user elects to use the default value(s), those value(s) will not be validated by any specified checks unless this parameter is set to 1.
date_format_display
str: Defaults to '%c'. This string is used to format any dates being printed to FH_OUT. See the UnixDate function from perldoc Date::Manip for details. Note this is a meaningful parameter only when used in conjunction if type is set to date.
date_format_return
str: Defaults to '%c'. This string is used to format dates returned by the get and validate methods. See Date::Manip's UnixDate function for details. Note this is a meaningful parameter only when used in conjunction if type is set to date.
FH_OUT
FH: Defaults to STDOUT. This filehandle will be used to print any messages to the user.
FH_IN
FH: Defaults to STDIN. This filehandle will be used to read any input from the user.
term_width
num: Defaults to 72. If the term_width of FH_OUT is less than the default or a value that you provide, the FH_OUT term_width will be used instead.
ReadMode
num: Sets the ReadMode for FH_IN during user prompting. Useful for turning terminal echo off for getting passwords; see Term::ReadKey for details. If this parameter is used, the ReadMode for FH_IN will be reset to 0 after each user input and in END processing.
dbh
obj: This is the database handle needed to execute any sql_checks. See perldoc DBI for details.
translate

aref: Translates validated user input into something else. Useful, for example, when you require the user to enter only one character for the sake of convenience, but you really want something more verbose returned. The aref may contain one or more translation rules, each of which is comprised of a check (see below) and a translation string. For example, when calling get with the following, a validated user input of 'p' would be translated into the string 'portrait' before being returned to you:

    translate   =>  [
                        [ 'eq p'  => 'portrait' ],
                        [ 'eq l'  => 'landscape' ],
                    ]
check

str, aref, qr//, coderef: This parameter accepts one string, one aref, one compiled regular expression (qr//), or one coderef. With these options you will be able to indicate one or more of the following kinds of checks to be used in validating data, as well as any error message you would like for each of the checks.

CHECK VARIETIES

Term::Interact comes with support for six varieties of check expressions:

sql_check
str: A SQL statement (i.e. 'SELECT field FROM table'). Will be used to generate a list of validation values from a database. Valid data is that which appears in the list.
regex_check
qr//: A compliled regular expression used to validate data. Valid data is that which matches the regular expression.
list_check
aref: An aref of values used to validate data. Valid data is that which appears in the list.
compare_check
str: A comparison test in string form. Valid data is that which satisfies the comparison test.
filetest_check
str: A filetest operator in string form. Valid data is that which satisfies the filetest operator.
custom_check
coderef: For special occasions (or to make use of Perl's built in functions), you can write your own custom check. This must be a reference to a function that accepts one value and returns true if that value is valid. Example: check => [ sub{getgrnam shift}, '%s is not a valid group' ]

SYNTAX

Possible values when specifying a single check:

  [   $check_aref,    $err_str    ]
           -or-
  [   $check_aref                 ]
           -or-
      $check_aref
           -or-
  [   $check_regex,   $err_str    ]
           -or-
  [   $check_regex                ]
           -or-
      $check_regex
           -or-
  [   $check_str,     $err_str    ]
           -or-
  [   $check_str                  ]
           -or-
      $check_str

Possible values when specifying multiple checks:

  [
    [ $check_aref,    $err_str  ],
    [ $check_aref               ],
      $check_aref,
    [ $check_regex,   $err_str  ],
    [ $check_regex              ],
      $check_regex,
    [ $check_str,     $err_str  ],
    [ $check_str                ],
      $check_str,
  ]

NOTE

This module steers clear of offering explicit checks like 'phone_number_check' or 'email_address_check'. In the author's opinion one may generally obtain all the convenience and code readability one needs via the built in varieties of checks. However, if you have regular need for an additional check you'll likely want to steer clear of the built in custom_check option (see above). You can more permanently add your own custom checks by subclassing Term::Interact and providing the desired checks as subroutines (all the check subs follow a simple API, just follow the pattern). Additionally you will need to modify the private _classify_check_type function.

AUTHOR

Term::Interact by Phil R Lawrence.

SUPPORT

Support is available by emailing the author directly: prl ~AT~ cpan ~DOT~ org

COPYRIGHT

The Term::Interact module is Copyright (c) 2002 Phil R Lawrence. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

NOTE

This module was developed while I was in the employ of Lehigh University. They kindly allowed me to have ownership of the work with the understanding that I would release it to open source. :-)

SEE ALSO

Text::Autoformat, Term::ReadKey, Date::Manip