Professional Web Applications Themes

Opening file units recursively - PERL Miscellaneous

I have an application that reads a list of pathnames, and the list can contain "include" lines each of which specifies the path of a file to go off and process, just like recursive C includes. However, I am having a lot of trouble getting the file units to open and close properly. The following is a short extract of the relevant code, which works apart from the fact that when wd_runcr() tries to close the 'include'd file the next level file turns out to be closed at the same time. Why do Perl file units have to be so ...

  1. #1

    Default Opening file units recursively

    I have an application that reads a list of pathnames, and the
    list can contain "include" lines each of which specifies the
    path of a file to go off and process, just like recursive C
    includes.

    However, I am having a lot of trouble getting the file units
    to open and close properly. The following is a short extract
    of the relevant code, which works apart from the fact that
    when wd_runcr() tries to close the 'include'd file the next
    level file turns out to be closed at the same time.

    Why do Perl file units have to be so _damned_ complicated
    and obscure, when being passed between functions? Couldn't
    the guy who first developed the language simply have used
    ordinary variables for them?!

    (I've also tried 'our' instead of 'local' No idea what
    either does, but the examples I've seen seem to indicate
    that for some reason something other than the usual 'my'
    is required.)

    use strict;

    :::

    sub wd_runcr
    {
    local ($filename, $fileunit) = _;

    no strict 'refs';

    open $fileunit, "< $filename"
    or wd_die "open ('$filename', 'r') failed:\n $!";

    use strict 'refs';

    while (<$fileunit>)
    {
    :::

    if ($arg[0] eq '%include')
    {
    wd_runcr ($arg[1], ++$fileunit);

    next;
    }

    :::
    }

    close $fileunit
    or wd_die "close ('$filename') failed:\n $!";
    }

    #------------------------------------------------------------

    :::

    foreach my $subsys (subsys)
    {
    my $file = "$subsys/$target_os_dir/wdruncr.txt";

    wd_runcr ("$subsys/$target_os_dir/wdruncr.txt", 'A00');
    }


    Thanks in anticipation.


    Cheers

    John Ramsden (john_ramsdenNOSPAMsagitta-ps.com)
    John Ramsden Guest

  2. #2

    Default Re: Opening file units recursively

    John Ramsden <john_ramsdensagitta-ps.com> wrote in comp.lang.perl.misc:
    > I have an application that reads a list of pathnames, and the
    > list can contain "include" lines each of which specifies the
    > path of a file to go off and process, just like recursive C
    > includes.
    >
    > However, I am having a lot of trouble getting the file units
    > to open and close properly. The following is a short extract
    > of the relevant code, which works apart from the fact that
    > when wd_runcr() tries to close the 'include'd file the next
    > level file turns out to be closed at the same time.
    >
    > Why do Perl file units have to be so _damned_ complicated
    > and obscure, when being passed between functions? Couldn't
    > the guy who first developed the language simply have used
    > ordinary variables for them?!
    Well, the guy apparently thought he could get away with filehandles
    that were global symbols.

    But times have changed and you *can* have filehandles in arbitrary
    variables these days.
    > (I've also tried 'our' instead of 'local' No idea what
    > either does,
    That's look-uppable. See "perldoc perlvar", "perldoc -f our",
    and "perldoc -f local".
    > but the examples I've seen seem to indicate
    > that for some reason something other than the usual 'my'
    > is required.)
    To the contrary, it's filehandles in lexical (my-) variables that makes
    a smooth solution to the include problem possible.

    [code snipped]

    Here is an example that prints out the lines as they arrive. Any other
    kind of processing could happen instead.

    sub copy_including {
    my $file = shift;
    open my $fh, $file or die "Can't read $file: $!";
    while ( <$fh> ) {
    if ( my $incl = extract_incl( $_) ) {
    copy_including( $incl);
    } else {
    print;
    }
    }
    }

    sub extract_incl {
    local $_ = shift;
    /#include\s*(.*)/;
    $1;
    }

    The significant bit in this code is "my $fh" in the open statement.
    This creates a new lexical $fh each time through, so opening $fh
    doesn't close a file that has been opened in this variable before.
    After return from a recursive call, the previous $fh is still around
    and points to the right place.

    Anno
    Anno Siegel Guest

  3. #3

    Default Re: Opening file units recursively

    John Ramsden <john_ramsdensagitta-ps.com> wrote:
    > However, I am having a lot of trouble getting the file units
    > to open and close properly. The following is a short extract
    > of the relevant code, which works apart from the fact that
    > when wd_runcr() tries to close the 'include'd file the next
    > level file turns out to be closed at the same time.

    Because $fileunit is a "package variable" (ie. a global variable).

    The "inner" recursive subroutines are messing up the values of
    variables used by the outer iterations.

    > Why do Perl file units

    What is a "file unit"?

    Do you mean "filehandle"?

    Do you mean "file descriptor"?

    Do you mean something else?

    > the guy who first developed the language

    "the guy" has a name. It is Larry.

    > (I've also tried 'our' instead of 'local' No idea what
    > either does,

    That is the cause of your problem, so you better keep at it until
    you do understand them. These may help with that:

    "Coping with Scoping":

    [url]http://perl.plover.com/FAQs/Namespaces.html[/url]

    and

    perldoc -q filehandle

    How can I pass/return a {Function, FileHandle, Array,
    Hash, Method, Regex}?


    --
    Tad McClellan SGML consulting
    [email]tadmcaugustmail.com[/email] Perl programming
    Fort Worth, Texas
    Tad McClellan Guest

  4. #4

    Default Re: Opening file units recursively

    [email]john_ramsdensagitta-ps.com[/email] (John Ramsden) wrote in message news:<d27434e.0309180412.76bea366posting.google.c om>...
    >
    > I have an application that reads a list of pathnames, and the
    > list can contain "include" lines each of which specifies the
    > path of a file to go off and process, just like recursive C
    > includes.
    Many thanks for the replies, which mentioned several interesting
    points that I'll investigate.

    On digging around the web shortly after posting I came across
    [url]http://www.stonehenge.com/merlyn/UnixReview/col19.html[/url], which
    explains the use of IO::File to do exactly the what I described.
    (I would have mentioned this earlier, but Google delays several
    hours before one's posts are visible.)

    But the 'my $fh' solution is probably even simpler than using
    IO::File.


    Cheers

    John Ramsden (john_ramsdensagitta-ps.com)
    John Ramsden Guest

  5. #5

    Default Re: Opening file units recursively

    John Ramsden <john_ramsdensagitta-ps.com> wrote in comp.lang.perl.misc:
    > [email]john_ramsdensagitta-ps.com[/email] (John Ramsden) wrote in message
    > news:<d27434e.0309180412.76bea366posting.google.c om>...
    > >
    > > I have an application that reads a list of pathnames, and the
    > > list can contain "include" lines each of which specifies the
    > > path of a file to go off and process, just like recursive C
    > > includes.
    >
    > Many thanks for the replies, which mentioned several interesting
    > points that I'll investigate.
    >
    > On digging around the web shortly after posting I came across
    > [url]http://www.stonehenge.com/merlyn/UnixReview/col19.html[/url], which
    > explains the use of IO::File to do exactly the what I described.
    > (I would have mentioned this earlier, but Google delays several
    > hours before one's posts are visible.)
    >
    > But the 'my $fh' solution is probably even simpler than using
    > IO::File.
    Well, the column is more than five years old, quite possibly lexical
    filehandles[*] weren't around then, or rather, weren't handled as smoothly.

    The advantage of lexical filehandles is that the solution is now straight-
    forward. Most programmers would write something similar in any recursive
    language where filehandles can be held in variables.

    It is much harder when you are stuck with global filehandles; recursion
    doesn't look so attractive then. Once you have the recursive solution,
    however, it can be retro-fit to package filehandles when you realize that
    you can localize such a filehandle by localizing its typeglob. That
    localizes everything under the name, including the filehandle. If you
    now use

    local *FH;
    open FH, ...;

    instead of

    open my $fh, ...;

    and read from "FH", recursion works as well with a package filehandle.
    It should even work under Perl 4, though I didn't try. Code below, if
    anyone has the opportunity and is so inclined...

    [1] "Lexical filehandle" is short for "reference to a typeglob that contains
    a filehandle, held in a lexical variable". They're so magic, they
    glow in the dark.

    Anno, who hasn't written Perl 4 for a long time

    -------------------------------------------------------------
    sub copy_including_4 {
    no strict 'vars'; # for Perl 5 compatibility
    local *FH;
    open FH, $_[ 0] or die "Can't read $_[ 0]: $!";
    while ( <FH> ) {
    if ( /^#include\s*(.*)/ ) {
    &copy_including_4( $1);
    } else {
    print;
    }
    }
    }
    Anno Siegel Guest

Similar Threads

  1. Device units to user space units?
    By water_s_lily@adobeforums.com in forum Adobe Acrobat SDK
    Replies: 0
    Last Post: September 11th, 09:48 AM
  2. Supspend opening the file after create pdf file from Adobe PDF
    By Ray_Li@adobeforums.com in forum Adobe Acrobat Windows
    Replies: 2
    Last Post: May 20th, 02:55 PM
  3. recursively finding file size/timestamp on a Mac / Solaris
    By Shishir Saxena in forum PERL Beginners
    Replies: 0
    Last Post: September 17th, 04:07 AM
  4. Opening JPG file with PE 2 in XP
    By Pete D in forum Adobe Photoshop Elements
    Replies: 4
    Last Post: July 29th, 12:13 AM
  5. Bitmaps are displaced when opening FH9 file-I need a test file
    By Delores in forum Macromedia Freehand
    Replies: 2
    Last Post: July 25th, 08:22 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139