Greetings, Monks.

Boy, do i have a doozy for you!!!

I have a program, which contains 2 functions. (well - more than 2, but only 2 are relevant). Both of them are recursive, and the second gets called from the first. The first one does some processing on database tables, and then calls itself to process that tables children. It then calls the second to process it's parents... Enter the explanatory code snippet:

#!perl <snip> buildSQL($starttable, $startwhere) <snip> . . . . . . sub buildSQL { my $table=shift; my $where=shift; $level++; $ischild{$table}=1; <snip> foreach my $child (keys($tables{$table})) { <snip> print STDERR "About to gen SQL for $child, child of $table\n" +if $table =~ m/Test2/; <snip> buildSQL($child,$wh); } buildParentSQL($table); $level--; } sub buildParentSQL () { my $table=shift; <snip> foreach my $parent (@{$parents{$table}}) { next if defined($ischild{$parent}; print STDERR "Generating parent SQL for $parent, parent of $ta +ble\n" if $parent =~ m/Test2/; <snip> buildParentSQL($parent); $level--; } }
Which looks OK to me. The plan is, it enters buildSQL, sets some data in a hash (ugly code which i've removed for brevity and sanity), and then calls itself for each child entity of the one it's just completed. Once it's done all the work on itself, and all of it's children, it's time to work on it's parents - hence the call to buildParentSQL.

What i expected to happen: A large stack of buildSQL would build up, setting $ischild for each one as it goes. Only once the last buildSQL has completed, should the buildParentSQL's start getting called.

Because of the next therein, any table which is a child gets ignored, but any which isn't get appropriately dealt with.

Now, the weird part. Enter sample output:

Generating parent SQL for Test1, parent of Test2 About to gen SQL for Test3, child of Test2 About to gen SQL for Test4, child of Test2

The first line of output comes from the second function (buildParentSQL)!! How can this be? Surely, SURELY, all the children from the first function should have done their output, before the second function even got called!

Now enter even more weirdness: I figured 'OK, It creates a pipeline of sorts, into which it's inserting the prints and things, and only flushes that when the function completes'. So I moved the buildParentSQL call to be the first thing in the buildSQL function (except for shifts etc), and ran it again. Identical output.

How can this be?

Hopefully, some-one knows whats going on here, because i can't figure it out... It must be something do with the recursiveness of it all, but to my mind it looks OK. Haven't tried in any other languages yet, though that may be a next step....

Ideas, suggestions, and the pointing out of stupid mistakes all welcome. (especially the last).


Thanks


In reply to Two recursive functions returning in unexpected order by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.