<font><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">On Thu, Mar 29, 2012 at 1:27 PM, Darin McBride <<a href="mailto:darin.mcbride@shaw.ca">darin.mcbride@shaw.ca</a>> wrote:</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">></span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> On Thursday March 29 2012 6:48:09 PM Zsbán Ambrus wrote:</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> > On 3/29/12, Fulko Hew <<a href="mailto:fulko.hew@gmail.com">fulko.hew@gmail.com</a>> wrote:</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> > >     foreach (`prog|prog|prog`) {</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> > ></span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> > > What I obviously need to do is to turn my obtainer() into an event driven</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> > > aspect too!  And I think what I want is an 'IO Watcher', but...</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> ></span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> > Take a look at the run_cmd function in the AnyEvent::Util module.  It</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> > spawns you a program (in this case you'll ask it spawn a shell so it</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> > interprets all those inner pipe to you) and handles reading its</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> > output.  When it's finished, split the output to lines.</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">></span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> If you really want to go all the way with AE here, making it entirely</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> asynchronous, run_cmd is still the right way, but you can set some callbacks</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> for stdout and stderr such that you get the lines as they come in.</span><br style="font-family:courier new,monospace">

<br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">I tried that (I thought correctly, as per below) and I get an error rather<br>than my callback being called.</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">Its probably something stupid, but I'm not seeing it...</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">(And I can't find any examples in the AnyEvent::Util module or its test directory.)</span><br style="font-family:courier new,monospace">

<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">Not a GLOB reference at /usr/lib/perl5/site_perl/5.8.8/AnyEvent/Util.pm line 592.</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">where the code looks like: </span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         if (defined eval { fileno $ob }) {</span><br style="font-family:courier new,monospace">

<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">my snippet is:</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">sub collector {</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">    my ($x) = @_;</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    print "collector got: $x\n";</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">}</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">$::cv = run_cmd "echo \"display chstatus (*)\" | runmqsc $mgrName",</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">                    ">" => \&collector;</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">>  I see</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> nothing in the docs that say, however, that you're guaranteed to get full</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> lines, though, in general, assuming short enough lines, that's what I've been</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> seeing in my own usage.  That may, however, be an artefact of how my</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> subprograms produce their output (they may flush on line breaks, which is a</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> reasonable default for stderr).</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">I got that too, that's why I'm testing what's (going to) happen with the example above.</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace"> </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> I have code that accumulates the output into a separate buffer, splits that on</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> line breaks, sends it on to the code that is interested, but keeps partial</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> lines hidden away in the buffer for the next callback, so that the business-</span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> logic code never sees a partial line, which greatly simplifies that code.</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">Would you share that with me?</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> </span><br style="font-family:courier new,monospace">

<span style="font-family:courier new,monospace">> Personally, I've done the same thing with IO::Select and IPC::Open3.</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">> AnyEvent::Util::run_cmd is FAR simpler to use, and to get right.</span><br style="font-family:courier new,monospace">

<br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"></font>