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

John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Experimenting and trying things, especially for this discussion group, I find that a lot of things are one-liners that can be done via -e. Some are difficult to do because of shell quoting issues, and some are a couple lines. Creating a file in the text editor, deciding on a name and saving it, then going to that directory on a command-line to run it seems overkill for something I should be able to do with -e or something like it.

So I've had it in the back of my head to make something as a shortcut. Implementing a "run contents as Perl" command for my usual text editor has issues: I still have to come up with a name, and it's not running under a console (text) environment.

So, I thought about a real simple Perl program that has a edit box and a Run button. (see end for concept code)

Now that it's underway, I'm thinking about other features. Here's a question: How can I separate out compiler errors from program's output? The program may itself write to STDERR, so if I can get Perl to write to someplace else... then the editor can parse errors and position the cursor. Note that I'm running another copy of Perl, not simply eval-ing the code, so it can always have a clean environment.

All thoughts welcome.

—John

use strict; use warnings; use utf8; use Tk; ${^WIDE_SYSTEM_CALLS}= 1; my $MW = new MainWindow; my $text= $MW->Scrolled(qw/Text -relief sunken -borderwidth 2 -wrap no +ne -height 30 -scrollbars e/) ->pack(qw/-expand yes -fill both/); my $frame= $MW->Frame()->pack(); $frame->Button( -text => 'Run', -command => \&do_run ) ->pack (-side => 'left'); $frame->Button( -text => 'Save' ) -> pack (-side =>'left'); $text->insert ('0.0', "use v5.6.1;\nuse strict;\nuse warnings;\n\n"); MainLoop; ################3 sub do_run { my $s= $text->get('1.0','end'); open OUTFILE, "> quick_run.perl" or die "Cannot save file."; print OUTFILE $s; close OUTFILE; system "perl quick_run.perl"; }

Replies are listed 'Best First'.
Re: QuickPerl: a step up from -e
by Abigail (Deacon) on Jul 05, 2001 at 02:14 UTC
    Personally, I would use a good editor, one that allows for programmable macros. Many vi-clones and certainly emacs do. Here's a macro I use (using the editor vile):
    18 store-macro save-file shell-command &cat "/opt/perl/bin/perl -wc " $cfilname ~endm
    It saves my current buffer, then runs perl -wc on the file, displaying the output. I can bind that to any keystroke I want. (Or, if I were kinky enough to use the mouse aware xvile, to a button or menu-item)

    Parsing the output of perl -wc (even with Perl if you want to, many vi-clones can have a Perl compiler/interpreter linked in) and positioning the cursor on the line of the first error would be a not to hard, logical extension.

    I certainly wouldn't want to cook up a Tk kludge, and edit in something else than my favourite editor.

    -- Abigail

      If you read my original post, you'd know why I wasn't satisfied with an editor command: lack of console environment. Editor is GUI. Unlike X, you don't have the console that started the graphical program still connected to stdout. Instead, the Win32 system has a somewhat different context. I've published a couple articles in the COBB Group journals on those differences and how programs can mix&match. Piping stdout to a pipe isn't right either, because Win32 doesn't have pseudoterminals and the program can sense that it's not really the console. The C RTL, for example, turns on buffering.

      —John

        Well, if you say you don't get console environment when run something from an editor on Windows, I believe you - but I'm very, very surprised your Tk solution does. After all, what that does is taking your code, putting it in a file, and executing it. Which is *exactly* what my macro does, except that it already finds the stuff to be run in a file. I don't know much about Windows, but I'd like to know which magic Windows performs that makes the system()ed program from Tk get a "console environment", while the program run from an editor doesn't.

        -- Abigail

Re: QuickPerl: a step up from -e
by jeroenes (Priest) on Jul 05, 2001 at 09:50 UTC
    The perl shell may provide everything you need. Stuff you type within curly braces is evaluated as perl, and you still have access to all normal shell features like pipelines, command line editing etc...

    Jeroen
    "We are not alone"(FZ)

Re: QuickPerl: a step up from -e
by tachyon (Chancellor) on Jul 05, 2001 at 01:58 UTC

    Why not just

    #!/usr/bin/perl package Run::Perl; print "Enter some perl: "; while ($_=<>) { chomp; exit unless $_; eval; print "\nEnter some perl: "; }

    tachyon

    s&&rsenoyhcatreve&&&s&n\w+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      That would completely miss the point, wouldn't it? You cannot edit what you ran before (and as a minor thing, you can't use newlines)

      -- Abigail

      Because the idea is to be able to edit and retry, as well as edit before trying. Just entering a few lines like that even loses the ability of editing it via command history.

      Yours takes one line at a time and executes it. It fills a different need, I suppose: trying variations of a syntax construct, for example, without having to type the perl-e part over and over. I'm thinking of larger multi-line programs.

        Is there someting wrong with using one of the many Perl IDE's available for both *nix and Win 32? I use Perl Builder 2 for Win 32 and Linux. You can type in as many lines as you want, edit to your hearts content, run at the press of a button, read the error codes, check the output, check vars, set breakpoints, and never save the file if you don't want to. Add syntax colour coding, a curly bracket matcher, access to the manpages, pod viewers, etc, etc, etc You can get a fully featured trial version here

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n\w+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

(bbfu) Re: QuickPerl: a step up from -e
by bbfu (Curate) on Jul 05, 2001 at 02:44 UTC

    How about doing a fork, redirecting STDERR in the child to a pipe who's other end is open in the parent, and then execing "perl quick_run.perl"? I don't know whether that will work or not but it's likely. Update: That is, of course, instead of doing the system call.

    HTH

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

      How about doing a fork ... That is, of course, instead of doing the system call.

      How do you think system is actually implemented? Under UNIX, system *is* doing a fork and an exec. Under Windows, there's no native fork, but the principle remains the same: what you are replacing system with is just what system is already doing.

      -- Abigail

        Yes, I'm aware that's how system is implemented. My point was more of doing the STDERR redirect after the fork but before the exec so that it wasn't changed for the parent. It seems, however, that John is using windows which doesn't support fork properly, so it's kind of pointless. :-) So I guess you would just have to redirect STDERR, do the system call, and then restore STDERR. *shrug*

        Update: See my other reply.

        bbfu
        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.

      Fork is a little odd in Windows, and doesn't really start a new process. So what will the exec do?!

      I think maybe redirect STDERR, and then run Perl feeding it a bootup script which redirects it again before running the real script, but I think that won't work because perl.exe will see and respect the change (again), too.

        So what will the exec do?!

        I have no idea. :-p

        Well, system is basically the same thing as fork/exec and my point was basically to do the STDERR redirect between the fork and the exec so that it wouldn't be (temporarily) redirected in the parent. I suppose that it's not really that big of a deal so you might as well just do:

        # # Note: UNTESTED!!! # sub do_run { # write file... local *OLDERR, *NEWERR; open(OLDERR, ">& STDERR") or die "Can't dup STDERR: $!"; pipe(NEWERR, STDERR) or die "Can't pipe: $!"; system "perl quick_run.perl"; open(STDERR, ">& OLDERR") or die "Can't restore STDERR: $!"; my @error_lines = <NEWERR>; return @error_lines; }

        bbfu
        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.

Re: QuickPerl: a step up from -e
by mattr (Curate) on Jul 05, 2001 at 14:24 UTC
    Just a followup on Emacs in case you haven't used it.. I don't know if XEmacs can do this on NT but XEmacs on Linux for example will let you open a shell in a separate frame of your window (or a separate window if you like) so that you can edit your program and run it in separate window panes. Probably you can do this with emacs in cygwin on windows if XEmacs for NT can't hack it.

    I do have an interactive perl shell (accumulate lines with readline and eval, I use it to try out Gimp macros) but you would have to create an editor to do what you want.