home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / perl / 5.10.0 / Term / UI.pm < prev   
Encoding:
Perl POD Document  |  2009-06-26  |  19.8 KB  |  621 lines

  1. package Term::UI;
  2.  
  3. use Carp;
  4. use Params::Check qw[check allow];
  5. use Term::ReadLine;
  6. use Locale::Maketext::Simple Style => 'gettext';
  7. use Term::UI::History;
  8.  
  9. use strict;
  10.  
  11. BEGIN {
  12.     use vars        qw[$VERSION $AUTOREPLY $VERBOSE $INVALID];
  13.     $VERBOSE    =   1;
  14.     $VERSION    =   '0.18';
  15.     $INVALID    =   loc('Invalid selection, please try again: ');
  16. }
  17.  
  18. push @Term::ReadLine::Stub::ISA, __PACKAGE__
  19.         unless grep { $_ eq __PACKAGE__ } @Term::ReadLine::Stub::ISA;
  20.  
  21.  
  22. =pod
  23.  
  24. =head1 NAME
  25.  
  26. Term::UI - Term::ReadLine UI made easy
  27.  
  28. =head1 SYNOPSIS
  29.  
  30.     use Term::UI;
  31.     use Term::ReadLine;
  32.  
  33.     my $term = Term::ReadLine->new('brand');
  34.  
  35.     my $reply = $term->get_reply(
  36.                     prompt => 'What is your favourite colour?',
  37.                     choices => [qw|blue red green|],
  38.                     default => blue,
  39.     );
  40.  
  41.     my $bool = $term->ask_yn(
  42.                         prompt => 'Do you like cookies?',
  43.                         default => 'y',
  44.                 );
  45.  
  46.  
  47.     my $string = q[some_command -option --no-foo --quux='this thing'];
  48.  
  49.     my ($options,$munged_input) = $term->parse_options($string);
  50.  
  51.  
  52.     ### don't have Term::UI issue warnings -- default is '1'
  53.     $Term::UI::VERBOSE = 0;
  54.  
  55.     ### always pick the default (good for non-interactive terms)
  56.     ### -- default is '0'
  57.     $Term::UI::AUTOREPLY = 1;
  58.     
  59.     ### Retrieve the entire session as a printable string:
  60.     $hist = Term::UI::History->history_as_string;
  61.     $hist = $term->history_as_string;
  62.  
  63. =head1 DESCRIPTION
  64.  
  65. C<Term::UI> is a transparent way of eliminating the overhead of having
  66. to format a question and then validate the reply, informing the user
  67. if the answer was not proper and re-issuing the question.
  68.  
  69. Simply give it the question you want to ask, optionally with choices
  70. the user can pick from and a default and C<Term::UI> will DWYM.
  71.  
  72. For asking a yes or no question, there's even a shortcut.
  73.  
  74. =head1 HOW IT WORKS
  75.  
  76. C<Term::UI> places itself at the back of the C<Term::ReadLine> 
  77. C<@ISA> array, so you can call its functions through your term object.
  78.  
  79. C<Term::UI> uses C<Term::UI::History> to record all interactions
  80. with the commandline. You can retrieve this history, or alter
  81. the filehandle the interaction is printed to. See the 
  82. C<Term::UI::History> manpage or the C<SYNOPSIS> for details.
  83.  
  84. =head1 METHODS
  85.  
  86. =head2 $reply = $term->get_reply( prompt => 'question?', [choices => \@list, default => $list[0], multi => BOOL, print_me => "extra text to print & record", allow => $ref] );
  87.  
  88. C<get_reply> asks a user a question, and then returns the reply to the
  89. caller. If the answer is invalid (more on that below), the question will
  90. be reposed, until a satisfactory answer has been entered.
  91.  
  92. You have the option of providing a list of choices the user can pick from
  93. using the C<choices> argument. If the answer is not in the list of choices
  94. presented, the question will be reposed.
  95.  
  96. If you provide a C<default>  answer, this will be returned when either
  97. C<$AUTOREPLY> is set to true, (see the C<GLOBAL VARIABLES> section further
  98. below), or when the user just hits C<enter>.
  99.  
  100. You can indicate that the user is allowed to enter multiple answers by
  101. toggling the C<multi> flag. Note that a list of answers will then be
  102. returned to you, rather than a simple string.
  103.  
  104. By specifying an C<allow> hander, you can yourself validate the answer
  105. a user gives. This can be any of the types that the Params::Check C<allow> 
  106. function allows, so please refer to that manpage for details. 
  107.  
  108. Finally, you have the option of adding a C<print_me> argument, which is
  109. simply printed before the prompt. It's printed to the same file handle
  110. as the rest of the questions, so you can use this to keep track of a
  111. full session of Q&A with the user, and retrieve it later using the
  112. C<< Term::UI->history_as_string >> function.
  113.  
  114. See the C<EXAMPLES> section for samples of how to use this function.
  115.  
  116. =cut
  117.  
  118. sub get_reply {
  119.     my $term = shift;
  120.     my %hash = @_;
  121.  
  122.     my $tmpl = {
  123.         default     => { default => undef,  strict_type => 1 },
  124.         prompt      => { default => '',     strict_type => 1, required => 1 },
  125.         choices     => { default => [],     strict_type => 1 },
  126.         multi       => { default => 0,      allow => [0, 1] },
  127.         allow       => { default => qr/.*/ },
  128.         print_me    => { default => '',     strict_type => 1 },
  129.     };
  130.  
  131.     my $args = check( $tmpl, \%hash, $VERBOSE )
  132.                 or ( carp( loc(q[Could not parse arguments]) ), return );
  133.  
  134.  
  135.     ### add this to the prompt to indicate the default
  136.     ### answer to the question if there is one.
  137.     my $prompt_add;
  138.     
  139.     ### if you supplied several choices to pick from,
  140.     ### we'll print them seperately before the prompt
  141.     if( @{$args->{choices}} ) {
  142.         my $i;
  143.  
  144.         for my $choice ( @{$args->{choices}} ) {
  145.             $i++;   # the answer counter -- but humans start counting
  146.                     # at 1 :D
  147.             
  148.             ### so this choice is the default? add it to 'prompt_add'
  149.             ### so we can construct a "foo? [DIGIT]" type prompt
  150.             $prompt_add = $i if $choice eq $args->{default};
  151.  
  152.             ### create a "DIGIT> choice" type line
  153.             $args->{print_me} .= sprintf "\n%3s> %-s", $i, $choice;
  154.         }
  155.  
  156.         ### we listed some choices -- add another newline for 
  157.         ### pretty printing
  158.         $args->{print_me} .= "\n" if $i;
  159.  
  160.         ### allowable answers are now equal to the choices listed
  161.         $args->{allow} = $args->{choices};
  162.  
  163.     ### no choices, but a default? set 'prompt_add' to the default
  164.     ### to construct a 'foo? [DEFAULT]' type prompt
  165.     } elsif ( defined $args->{default} ) {
  166.         $prompt_add = $args->{default};
  167.     }
  168.  
  169.     ### we set up the defaults, prompts etc, dispatch to the readline call
  170.     return $term->_tt_readline( %$args, prompt_add => $prompt_add );
  171.  
  172.  
  173. =head2 $bool = $term->ask_yn( prompt => "your question", [default => (y|1,n|0), print_me => "extra text to print & record"] )
  174.  
  175. Asks a simple C<yes> or C<no> question to the user, returning a boolean
  176. indicating C<true> or C<false> to the caller.
  177.  
  178. The C<default> answer will automatically returned, if the user hits 
  179. C<enter> or if C<$AUTOREPLY> is set to true. See the C<GLOBAL VARIABLES>
  180. section further below.
  181.  
  182. Also, you have the option of adding a C<print_me> argument, which is
  183. simply printed before the prompt. It's printed to the same file handle
  184. as the rest of the questions, so you can use this to keep track of a
  185. full session of Q&A with the user, and retrieve it later using the
  186. C<< Term::UI->history_as_string >> function.
  187.  
  188.  
  189. See the C<EXAMPLES> section for samples of how to use this function.
  190.  
  191. =cut
  192.  
  193. sub ask_yn {
  194.     my $term = shift;
  195.     my %hash = @_;
  196.  
  197.     my $tmpl = {
  198.         default     => { default => undef, allow => [qw|0 1 y n|],
  199.                                                             strict_type => 1 },
  200.         prompt      => { default => '', required => 1,      strict_type => 1 },
  201.         print_me    => { default => '',                     strict_type => 1 },        
  202.         multi       => { default => 0,                      no_override => 1 },
  203.         choices     => { default => [qw|y n|],              no_override => 1 },
  204.         allow       => { default => [qr/^y(?:es)?$/i, qr/^n(?:o)?$/i],
  205.                          no_override => 1
  206.                        },
  207.     };
  208.  
  209.     my $args = check( $tmpl, \%hash, $VERBOSE ) or return undef;
  210.     
  211.     ### uppercase the default choice, if there is one, to be added
  212.     ### to the prompt in a 'foo? [Y/n]' type style.
  213.     my $prompt_add;
  214.     {   my @list = @{$args->{choices}};
  215.         if( defined $args->{default} ) {
  216.  
  217.             ### if you supplied the default as a boolean, rather than y/n
  218.             ### transform it to a y/n now
  219.             $args->{default} = $args->{default} =~ /\d/ 
  220.                                 ? { 0 => 'n', 1 => 'y' }->{ $args->{default} }
  221.                                 : $args->{default};
  222.         
  223.             @list = map { lc $args->{default} eq lc $_
  224.                                 ? uc $args->{default}
  225.                                 : $_
  226.                     } @list;
  227.         }
  228.  
  229.         $prompt_add .= join("/", @list);
  230.     }
  231.  
  232.     my $rv = $term->_tt_readline( %$args, prompt_add => $prompt_add );
  233.     
  234.     return $rv =~ /^y/i ? 1 : 0;
  235. }
  236.  
  237.  
  238.  
  239. sub _tt_readline {
  240.     my $term = shift;
  241.     my %hash = @_;
  242.  
  243.     local $Params::Check::VERBOSE = 0;  # why is this?
  244.     local $| = 1;                       # print ASAP
  245.  
  246.  
  247.     my ($default, $prompt, $choices, $multi, $allow, $prompt_add, $print_me);
  248.     my $tmpl = {
  249.         default     => { default => undef,  strict_type => 1, 
  250.                             store => \$default },
  251.         prompt      => { default => '',     strict_type => 1, required => 1,
  252.                             store => \$prompt },
  253.         choices     => { default => [],     strict_type => 1, 
  254.                             store => \$choices },
  255.         multi       => { default => 0,      allow => [0, 1], store => \$multi },
  256.         allow       => { default => qr/.*/, store => \$allow, },
  257.         prompt_add  => { default => '',     store => \$prompt_add },
  258.         print_me    => { default => '',     store => \$print_me },
  259.     };
  260.  
  261.     check( $tmpl, \%hash, $VERBOSE ) or return;
  262.  
  263.     ### prompts for Term::ReadLine can't be longer than one line, or
  264.     ### it can display wonky on some terminals.
  265.     history( $print_me ) if $print_me;
  266.  
  267.     
  268.     ### we might have to add a default value to the prompt, to
  269.     ### show the user what will be picked by default:
  270.     $prompt .= " [$prompt_add]: " if $prompt_add;
  271.  
  272.  
  273.     ### are we in autoreply mode?
  274.     if ($AUTOREPLY) {
  275.         
  276.         ### you used autoreply, but didnt provide a default!
  277.         carp loc(   
  278.             q[You have '%1' set to true, but did not provide a default!],
  279.             '$AUTOREPLY' 
  280.         ) if( !defined $default && $VERBOSE);
  281.  
  282.         ### print it out for visual feedback
  283.         history( join ' ', grep { defined } $prompt, $default );
  284.         
  285.         ### and return the default
  286.         return $default;
  287.     }
  288.  
  289.  
  290.     ### so, no AUTOREPLY, let's see what the user will answer
  291.     LOOP: {
  292.         
  293.         ### annoying bug in T::R::Perl that mucks up lines with a \n
  294.         ### in them; So split by \n, save the last line as the prompt
  295.         ### and just print the rest
  296.         {   my @lines   = split "\n", $prompt;
  297.             $prompt     = pop @lines;
  298.             
  299.             history( "$_\n" ) for @lines;
  300.         }
  301.         
  302.         ### pose the question
  303.         my $answer  = $term->readline($prompt);
  304.         $answer     = $default unless length $answer;
  305.  
  306.         $term->addhistory( $answer ) if length $answer;
  307.  
  308.         ### add both prompt and answer to the history
  309.         history( "$prompt $answer", 0 );
  310.  
  311.         ### if we're allowed to give multiple answers, split
  312.         ### the answer on whitespace
  313.         my @answers = $multi ? split(/\s+/, $answer) : $answer;
  314.  
  315.         ### the return value list
  316.         my @rv;
  317.         
  318.         if( @$choices ) {
  319.             
  320.             for my $answer (@answers) {
  321.                 
  322.                 ### a digit implies a multiple choice question, 
  323.                 ### a non-digit is an open answer
  324.                 if( $answer =~ /\D/ ) {
  325.                     push @rv, $answer if allow( $answer, $allow );
  326.                 } else {
  327.  
  328.                     ### remember, the answer digits are +1 compared to
  329.                     ### the choices, because humans want to start counting
  330.                     ### at 1, not at 0 
  331.                     push @rv, $choices->[ $answer - 1 ] 
  332.                         if $answer > 0 && defined $choices->[ $answer - 1];
  333.                 }    
  334.             }
  335.      
  336.         ### no fixed list of choices.. just check if the answers
  337.         ### (or otherwise the default!) pass the allow handler
  338.         } else {       
  339.             push @rv, grep { allow( $_, $allow ) }
  340.                         scalar @answers ? @answers : ($default);  
  341.         }
  342.  
  343.         ### if not all the answers made it to the return value list,
  344.         ### at least one of them was an invalid answer -- make the 
  345.         ### user do it again
  346.         if( (@rv != @answers) or 
  347.             (scalar(@$choices) and not scalar(@answers)) 
  348.         ) {
  349.             $prompt = $INVALID;
  350.             $prompt .= "[$prompt_add] " if $prompt_add;
  351.             redo LOOP;
  352.  
  353.         ### otherwise just return the answer, or answers, depending
  354.         ### on the multi setting
  355.         } else {
  356.             return $multi ? @rv : $rv[0];
  357.         }
  358.     }
  359. }
  360.  
  361. =head2 ($opts, $munged) = $term->parse_options( STRING );
  362.  
  363. C<parse_options> will convert all options given from an input string
  364. to a hash reference. If called in list context it will also return
  365. the part of the input string that it found no options in.
  366.  
  367. Consider this example:
  368.  
  369.     my $str =   q[command --no-foo --baz --bar=0 --quux=bleh ] .
  370.                 q[--option="some'thing" -one-dash -single=blah' arg];
  371.  
  372.     my ($options,$munged) =  $term->parse_options($str);
  373.  
  374.     ### $options would contain: ###
  375.     $options = {
  376.                 'foo'       => 0,
  377.                 'bar'       => 0,
  378.                 'one-dash'  => 1,
  379.                 'baz'       => 1,
  380.                 'quux'      => 'bleh',
  381.                 'single'    => 'blah\'',
  382.                 'option'    => 'some\'thing'
  383.     };
  384.  
  385.     ### and this is the munged version of the input string,
  386.     ### ie what's left of the input minus the options
  387.     $munged = 'command arg';
  388.  
  389. As you can see, you can either use a single or a double C<-> to
  390. indicate an option.
  391. If you prefix an option with C<no-> and do not give it a value, it
  392. will be set to 0.
  393. If it has no prefix and no value, it will be set to 1.
  394. Otherwise, it will be set to its value. Note also that it can deal
  395. fine with single/double quoting issues.
  396.  
  397. =cut
  398.  
  399. sub parse_options {
  400.     my $term    = shift;
  401.     my $input   = shift;
  402.  
  403.     my $return = {};
  404.  
  405.     ### there's probably a more elegant way to do this... ###
  406.     while ( $input =~ s/(?:^|\s+)--?([-\w]+=("|').+?\2)(?=\Z|\s+)//  or
  407.             $input =~ s/(?:^|\s+)--?([-\w]+=\S+)(?=\Z|\s+)//         or
  408.             $input =~ s/(?:^|\s+)--?([-\w]+)(?=\Z|\s+)//
  409.     ) {
  410.         my $match = $1;
  411.  
  412.         if( $match =~ /^([-\w]+)=("|')(.+?)\2$/ ) {
  413.             $return->{$1} = $3;
  414.  
  415.         } elsif( $match =~ /^([-\w]+)=(\S+)$/ ) {
  416.             $return->{$1} = $2;
  417.  
  418.         } elsif( $match =~ /^no-?([-\w]+)$/i ) {
  419.             $return->{$1} = 0;
  420.  
  421.         } elsif ( $match =~ /^([-\w]+)$/ ) {
  422.             $return->{$1} = 1;
  423.  
  424.         } else {
  425.             carp(loc(q[I do not understand option "%1"\n], $match)) if $VERBOSE;
  426.         }
  427.     }
  428.  
  429.     return wantarray ? ($return,$input) : $return;
  430. }
  431.  
  432. =head2 $str = $term->history_as_string
  433.  
  434. Convenience wrapper around C<< Term::UI::History->history_as_string >>.
  435.  
  436. Consult the C<Term::UI::History> man page for details.
  437.  
  438. =cut
  439.  
  440. sub history_as_string { return Term::UI::History->history_as_string };
  441.  
  442. 1;
  443.  
  444. =head1 GLOBAL VARIABLES
  445.  
  446. The behaviour of Term::UI can be altered by changing the following
  447. global variables:
  448.  
  449. =head2 $Term::UI::VERBOSE
  450.  
  451. This controls whether Term::UI will issue warnings and explanations
  452. as to why certain things may have failed. If you set it to 0,
  453. Term::UI will not output any warnings.
  454. The default is 1;
  455.  
  456. =head2 $Term::UI::AUTOREPLY
  457.  
  458. This will make every question be answered by the default, and warn if
  459. there was no default provided. This is particularly useful if your
  460. program is run in non-interactive mode.
  461. The default is 0;
  462.  
  463. =head2 $Term::UI::INVALID
  464.  
  465. This holds the string that will be printed when the user makes an
  466. invalid choice.
  467. You can override this string from your program if you, for example,
  468. wish to do localization.
  469. The default is C<Invalid selection, please try again: >
  470.  
  471. =head2 $Term::UI::History::HISTORY_FH
  472.  
  473. This is the filehandle all the print statements from this module
  474. are being sent to. Please consult the C<Term::UI::History> manpage
  475. for details.
  476.  
  477. This defaults to C<*STDOUT>.
  478.  
  479. =head1 EXAMPLES
  480.  
  481. =head2 Basic get_reply sample
  482.  
  483.     ### ask a user (with an open question) for their favourite colour
  484.     $reply = $term->get_reply( prompt => 'Your favourite colour? );
  485.     
  486. which would look like:
  487.  
  488.     Your favourite colour? 
  489.  
  490. and C<$reply> would hold the text the user typed.
  491.  
  492. =head2 get_reply with choices
  493.  
  494.     ### now provide a list of choices, so the user has to pick one
  495.     $reply = $term->get_reply(
  496.                 prompt  => 'Your favourite colour?',
  497.                 choices => [qw|red green blue|] );
  498.                 
  499. which would look like:
  500.  
  501.       1> red
  502.       2> green
  503.       3> blue
  504.     
  505.     Your favourite colour? 
  506.                 
  507. C<$reply> will hold one of the choices presented. C<Term::UI> will repose
  508. the question if the user attempts to enter an answer that's not in the
  509. list of choices. The string presented is held in the C<$Term::UI::INVALID>
  510. variable (see the C<GLOBAL VARIABLES> section for details.
  511.  
  512. =head2 get_reply with choices and default
  513.  
  514.     ### provide a sensible default option -- everyone loves blue!
  515.     $reply = $term->get_reply(
  516.                 prompt  => 'Your favourite colour?',
  517.                 choices => [qw|red green blue|],
  518.                 default => 'blue' );
  519.  
  520. which would look like:
  521.  
  522.       1> red
  523.       2> green
  524.       3> blue
  525.     
  526.     Your favourite colour? [3]:  
  527.  
  528. Note the default answer after the prompt. A user can now just hit C<enter>
  529. (or set C<$Term::UI::AUTOREPLY> -- see the C<GLOBAL VARIABLES> section) and
  530. the sensible answer 'blue' will be returned.
  531.  
  532. =head2 get_reply using print_me & multi
  533.  
  534.     ### allow the user to pick more than one colour and add an 
  535.     ### introduction text
  536.     @reply = $term->get_reply(
  537.                 print_me    => 'Tell us what colours you like', 
  538.                 prompt      => 'Your favourite colours?',
  539.                 choices     => [qw|red green blue|],
  540.                 multi       => 1 );
  541.  
  542. which would look like:
  543.  
  544.     Tell us what colours you like
  545.       1> red
  546.       2> green
  547.       3> blue
  548.     
  549.     Your favourite colours?
  550.  
  551. An answer of C<3 2 1> would fill C<@reply> with C<blue green red>
  552.  
  553. =head2 get_reply & allow
  554.  
  555.     ### pose an open question, but do a custom verification on 
  556.     ### the answer, which will only exit the question loop, if 
  557.     ### the answer matches the allow handler.
  558.     $reply = $term->get_reply(
  559.                 prompt  => "What is the magic number?",
  560.                 allow   => 42 );
  561.                 
  562. Unless the user now enters C<42>, the question will be reposed over
  563. and over again. You can use more sophisticated C<allow> handlers (even
  564. subroutines can be used). The C<allow> handler is implemented using
  565. C<Params::Check>'s C<allow> function. Check its manpage for details.
  566.  
  567. =head2 an elaborate ask_yn sample
  568.  
  569.     ### ask a user if he likes cookies. Default to a sensible 'yes'
  570.     ### and inform him first what cookies are.
  571.     $bool = $term->ask_yn( prompt   => 'Do you like cookies?',
  572.                            default  => 'y',
  573.                            print_me => 'Cookies are LOVELY!!!' ); 
  574.  
  575. would print:                           
  576.  
  577.     Cookies are LOVELY!!!
  578.     Do you like cookies? [Y/n]: 
  579.  
  580. If a user then simply hits C<enter>, agreeing with the default, 
  581. C<$bool> would be set to C<true>. (Simply hitting 'y' would also 
  582. return C<true>. Hitting 'n' would return C<false>)
  583.  
  584. We could later retrieve this interaction by printing out the Q&A 
  585. history as follows:
  586.  
  587.     print $term->history_as_string;
  588.  
  589. which would then print:
  590.  
  591.     Cookies are LOVELY!!!
  592.     Do you like cookies? [Y/n]:  y
  593.  
  594. There's a chance we're doing this non-interactively, because a console
  595. is missing, the user indicated he just wanted the defaults, etc.
  596.  
  597. In this case, simply setting C<$Term::UI::AUTOREPLY> to true, will
  598. return from every question with the default answer set for the question.
  599. Do note that if C<AUTOREPLY> is true, and no default is set, C<Term::UI>
  600. will warn about this and return C<undef>.
  601.  
  602. =head1 See Also
  603.  
  604. C<Params::Check>, C<Term::ReadLine>, C<Term::UI::History>
  605.  
  606. =head1 BUG REPORTS
  607.  
  608. Please report bugs or other issues to E<lt>bug-term-ui@rt.cpan.org<gt>.
  609.  
  610. =head1 AUTHOR
  611.  
  612. This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
  613.  
  614. =head1 COPYRIGHT
  615.  
  616. This library is free software; you may redistribute and/or modify it 
  617. under the same terms as Perl itself.
  618.  
  619. =cut
  620.