http://www.perlmonks.org?node_id=496359


in reply to Re: Using IO::Prompt's menu
in thread Using IO::Prompt's menu

Thanks for your time Tanktalus.

I forgot that shift does that with @ARGV:

If ARRAY is omitted, shifts the @_ array within the lexical scope of s +ubroutines and formats, and the @ARGV array at file scopes or within the lexical scopes establ +ished by the "eval ’’",

But I am still puzzled as to why IO::Prompt would do that. If you are presenting a menu, you want the user to select something, not pass in an option on the commandline. If you did, you would use Getopt::* for that.

Do you think this is a bug?
Gavin.

Walking the road to enlightenment... I found a penguin and a camel on the way.....
Fancy a yourname@perl.me.uk? Just ask!!!

Replies are listed 'Best First'.
Re^3: Using IO::Prompt's menu
by TheDamian (Vicar) on Oct 01, 2005 at 01:34 UTC
    But I am still puzzled as to why IO::Prompt would do that.

    IO::Prompt is designed to be a drop-in replacement for the "diamond operator" (i.e. for: <>). It writes out its prompt to STDOUT and then does a <> to get the reply.

    But the diamond operator is just a shorthand for <ARGV>, a readline on the magic filehandle that normally is attached to STDIN...unless you specify a filename on the commandline.

    So it shouldn't really be a surprise that, if you put something on the commandline (as you typically do when running this program), <ARGV> attempts to open-and-read from that something. That's just standard Perl behaviour...which prompt() valiantly tries to preserve.

    Of course, standard Perl behaviour isn't always what you want (as in this example). And that's why prompt() also has a -tty option, so you can explicitly say "Don't work like Perl's <ARGV> works; always read from the terminal instead".

    You might like to try replacing:

    my $choice = prompt 'Please choose your format...', -1, -menu => [ 'PAL', 'NTSC', 'Quit', ];

    (which means "Prompt, reading from wherever <ARGV> reads from") with this:

    my $choice = prompt -tty, 'Please choose your format...', -1, -menu => [ 'PAL', 'NTSC', 'Quit', ];

    (which means "Prompt, always reading from the terminal").

    If you are presenting a menu, you want the user to select something, not pass in an option on the commandline. If you did, you would use Getopt::* for that.

    That's not quite what's happening here. If <ARGV> (or prompt()) finds a string on the commandline, it tries to open the file whose name is that string, and then reads from that file.

    Why would you want that? Well, you might want that behaviour because you've written a script that automates the use of your program, and you want to feed the program its required input from a "prerecorded" file, which you specify on the commandline. Again, this is standard Perl behaviour, not my invention. I'm merely trying to preserve it when replacing <ARGV>.

    As you can see, "least surprise" is a difficult thing to achieve. It depends entirely on what people find surprising, which in turn depends on what features of Perl they're familiar with.

    However, it certainly would be a good idea for me to rework the docs a little to emphasize the "just like <ARGV>" behaviour of the module, with all that implies.

    Thanks for bringing this "surprise" to my attention.

      "It depends entirely on what people find surprising, which in turn depends on what features of Perl they're familiar with."

      I think this says it all for me ;-)

      Walking the road to enlightenment... I found a penguin and a camel on the way.....
      Fancy a yourname@perl.me.uk? Just ask!!!
Re^3: Using IO::Prompt's menu
by Tanktalus (Canon) on Sep 30, 2005 at 14:47 UTC

    First off, I submitted a bug for the Want prereq. Guess who responded. TheDamian. Very quickly, too, I might add. "Patched." So perhaps he can chime in here.

    My guess is that it'll be viewed as a documentation bug and that this is viewed as a "feature". Personally, I agree that it's not expected and, although I think it may not follow the principle of least surprise, I can also see how it could be seen as a "cool" feature.

    I would think that it should be an option, though, to the prompt function. "-parseargv", perhaps. Default would be to ignore @ARGV. This way, we get the principle of least surprise while still keeping the cool feature. The downside to this is that it would break any scripts that rely on the current behaviour. Not breaking these scripts, however, would break the principle of least surprise, IMO.

    But we'll have to leave it to TheDamian to decide. After all, I'm just but a young whippersnapper who barely knows the difference between map and for, nevermind an esteemed user of TheDamian's modules. ;-)