Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re^3: General pattern for interactive text-mode script?

by apl (Monsignor)
on Jul 03, 2008 at 23:19 UTC ( #695494=note: print w/replies, xml ) Need Help??

in reply to Re^2: General pattern for interactive text-mode script?
in thread General pattern for interactive text-mode script?

You have the sense of it, though I'd change:
'Major task to perform?' => ['task_1','task_2','task_2'],
to something like
'Major task to perform?' => { answers => [ 'Add', 'Delete', 'Rename' ], keys => [ 'task_1','task_2', 'task_2' ], },
This way if the user enters 'Add'. the next hash key you'd use is 'task_1'. (Make certain to programmatically test that there are as many keys as there are answers.)

This handles compressing all of the prompts you were talking about. The next problem is: what happens when you get to the end of the user input? You always need to keep track of the last key you used, and you need some way to indicate that you're at a terminal node. (Perhaps a blank key could indicate this.)

Your example would then become:

my $current_key = 'Major task to perform?'; while ( my $choice = prompt( $current_key, ...)) { # set INDEX to offset of $choice in $structure{ $current_key }{ans +wers} # if $structure{$current_key}{keys}[INDEX] is empty # break out of loop; you;'re in a terminal state # else $current_key = $structure{$current_key}{keys}[INDEX] } <p>A lot of the code is left as an exercise to the reader. Good luck w +ith your class.

Replies are listed 'Best First'.
Re^4: General pattern for interactive text-mode script?
by Tanktalus (Canon) on Jul 04, 2008 at 14:17 UTC

    Minor nit, but I prefer not to use indices whenever possible. In C, they're basically required. That's fine. But you shouldn't need them in C++ or Perl where we have proper iterators.

    So, instead of what you have, I'd combine them into a single list:

    'Major task to perform' => [ { input => 'Add', next => 'task_1' }, { input => 'Delete', next => 'task_2' }, { input => 'Rename', next => 'task_3' }, ],
    This should perform about as well as your method, but without the need for an index. As you loop through the hashrefs, once you find the input given, you already have the hashref with the details about whatever else you want. Further, you can very easily add additional fields if you find the need to. And if there is a long list of possible inputs, lining up the input with the associated task or next key or whatever will be trivial - not so with multiple array refs where you will have to manually ensure everything lines up even when you have 30 or 40 possible next states.

    Or, if I was going to be case sensitive anyway (or I was willing to lc everything), set it up in a hash based on the inputs and be even faster:

    'Major task to perform' => { 'add' => { next => 'task_1', help => 'Add something to the intern +al list' }, 'delete' => { next => 'task_2', help => 'Rename something (didn't ex +pect that, did you)' }, 'rename' => { next => 'task_3', help => 'Move something to a new loc +ation (didn't expect that, either, huh?)' }, },
    When you get an input word, just lc it, and look it up for what the next state is. As you can see, I've gone and added extra info, which is trivial to do in hashes: if you get the 'help' word, you could loop through the hash (possibly by sorting on the key first, or maybe sorting based on a key in the value hash, e.g., "sort_order => $n"), printing the key and the help (Text::Table may help here). All the information is co-located. (In a larger system, it's arguable that the help should go with 'next' rather than 'this', but that's merely implementation details - I'm talking about a design that is more flexible and easier to maintain.)

      Excellent suggestions. (I am, self-admittedly, a dinosaur. While I love Perl and like C++, I generally think in Fortran...)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://695494]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2018-06-23 10:35 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (125 votes). Check out past polls.