Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the IO-Interactive CPAN distribution.

Report information
The Basics
Id: 24823
Status: resolved
Priority: 0/
Queue: IO-Interactive

People
Owner: Nobody in particular
Requestors: ipluta [...] wp.pl
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: is_interactive() and command line arguments
Date: Tue, 06 Feb 2007 20:17:39 +0100
To: bug-IO-Interactive [...] rt.cpan.org
From: Ireneusz Pluta <ipluta [...] wp.pl>
Hello, it seems that is_interactive() returns 0 when a script using IO::Interactive is invoked with any command line parameters (causing @ARGV > 0). Here is my test script and its output when invoked without and with a parameter: 526-ipluta@perkoz:~/debug$ cat interactive.pl #!/usr/bin/perl -w use IO::Interactive qw(is_interactive); if (is_interactive()) { print "interactive\n\n"; } else { print "NOT interactive\n\n"; } 527-ipluta@perkoz:~/debug$ ./interactive.pl interactive 528-ipluta@perkoz:~/debug$ ./interactive.pl param NOT interactive Is this a bug? However, a quick hack with making a local @ARGV empty and testing is_interactive() in a code block seems to work for me: 531-ipluta@perkoz:~/debug$ cat interactive1.pl #!/usr/bin/perl -w use IO::Interactive qw(is_interactive); { local @ARGV = (); if (is_interactive()) { print "interactive\n\n"; } else { print "NOT interactive\n\n"; } } 532-ipluta@perkoz:~/debug$ ./interactive1.pl interactive 533-ipluta@perkoz:~/debug$ ./interactive1.pl param interactive I am not sure if this is a correct universal workaround. But even if that, this case is not mentioned anywhere in the documentation, so I am sending this post. Some more details of my system: 535-ipluta@perkoz:~/debug$ perl -MIO::Interactive -e 'print IO::Interactive->VERSION, "\n";' 0.000003 536-ipluta@perkoz:~/debug$ perl -v This is perl, v5.8.6 built for i386-freebsd-64int <...> 537-ipluta@perkoz:~/debug$ uname -a FreeBSD perkoz.cmr.net.pl 4.10-RELEASE FreeBSD 4.10-RELEASE #6: Mon Sep 20 11:29:40 CEST 2004 ipluta@perkoz.omd.pl:/usr/src/sys/compile/PERKOZ i386 Best regards Ireneusz Pluta
On Tue Feb 06 14:18:06 2007, ipluta@wp.pl wrote: Show quoted text
> Is this a bug?
It seems to be deliberate, it's mentioned in the comments. # If *ARGV isn't opened, it will be interactive if *STDIN is attached # to a terminal and either there are no files specified on the command line # or if there are files and the first is the magic '-' file I would argue that the presence of command line arguments says nothing about intractability. It assumes that everything which can be entered on the command line can be entered interactively and vice versa. And that you'd want to. Here's a simple counter-example: ./YAML-0.66$ perl Makefile.PL INSTALL_BASE=~ *** WARNING *** This release breaks compatibility with versions earlier than version 0.60 of YAML::Syck and YAML.pm when serializing blessed references. See the COMPATIBILITY file for more information. Continue installing YAML.pm? [y] The time hammered algorithm used in MakeMaker's prompt() routine is this: my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)); Which is to say... 1) STDIN is a tty 2) STDOUT is a tty 3) STDOUT is not a file or special character file 1 must be true, that much is obvious. On the theory that the user must be able to see the output we also check STDOUT. If STDOUT is a tty that's fine. If it's going to a file or something like /dev/null, we assume the user can't see the output and it's not interactive. STDOUT to a pipe is fine to allow things like tee.
The attached patch fixes is_interactive() to ignore command line arguments (except for -). It also fixes the docs to explain that is_interactive() defaults to the currently selected filehandle and not necessarily STDOUT. I'm not so sure that's a good idea, but it's what the code does. I didn't touch the -c case for piped STDOUT.
--- t/is_interactive.t (revision 41361) +++ t/is_interactive.t (revision 41362) @@ -1,15 +1,40 @@ +#!/usr/bin/perl -w + +use Test::More 'no_plan'; + use IO::Interactive qw( is_interactive ); -print "1..2\n"; +# Tests which depend on not being connected to a terminal +SKIP: { + skip "connected to a terminal", 2 if -t *STDIN && -t *STDOUT; -if (-t *STDIN && -t *STDOUT) { - print "ok 1\n" if is_interactive(); - print "ok 2\n" if is_interactive(*STDOUT); + ok !is_interactive(); + ok !is_interactive(*STDOUT); } -else { - print "not " if is_interactive(); - print "ok 1\n"; - print "not " if is_interactive(*STDOUT); - print "ok 2\n"; + +# Tests which depend on being connected to a terminal. +SKIP: { + skip "not connected to a terminal", 7 unless -t *STDIN && -t *STDOUT; + + ok is_interactive(); + ok is_interactive(*STDOUT); + + { + ok open my $manifest_fh, '<', "MANIFEST"; # any ol file will do. + ok !is_interactive($manifest_fh); + + my $old_fh = select $manifest_fh; + ok !is_interactive(), 'defaults to selected filehandle'; + select $old_fh; + } + + { + local @ARGV = qw(-); + + ok is_interactive(); + + @ARGV = (1,2,3); + ok is_interactive(); + } } --- lib/IO/Interactive.pm (revision 41361) +++ lib/IO/Interactive.pm (revision 41362) @@ -26,10 +26,9 @@ } # If *ARGV isn't opened, it will be interactive if *STDIN is attached - # to a terminal and either there are no files specified on the command line - # or if there are files and the first is the magic '-' file + # to a terminal. else { - return -t *STDIN && (@ARGV==0 || $ARGV[0] eq '-'); + return -t *STDIN; } } @@ -164,16 +163,17 @@ =item C<is_interactive()> -This subroutine returns true if C<*ARGV> and C<*STDOUT> are connected to -the terminal. The test is considerably more sophisticated than: +This subroutine returns true if C<*ARGV> and the currently selected +filehandle (usually C<*STDOUT>) are connected to the terminal. The +test is considerably more sophisticated than: -t *ARGV && -t *STDOUT as it takes into account the magic behaviour of C<*ARGV>. You can also pass C<is_interactive> a writable filehandle, in which case it -requires that filehandle be connected to a terminal (instead of C<*STDOUT>). -The usual suspect here is C<*STDERR>: +requires that filehandle be connected to a terminal (instead of the +currently selected). The usual suspect here is C<*STDERR>: if ( is_interactive(*STDERR) ) { carp $warning;
Patch applied in 0.0.4