in reply to Re: Re: Re: Out of memory.
in thread Out of memory.

Ew. map in void context. Hand rolled directory traversal (though that's not as bad on Win32). How about
use File::Find; my $size; find(sub { $size += -s _ if -f }, $TargetPath);
(Yes, File::Find is slower than hand rolled traversal. A heck of a lot less (and clearer) code, though, and still beats the dir /s approach by miles.)

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Re^4: Out of memory.
by BrowserUk (Patriarch) on Jul 23, 2003 at 12:19 UTC

    It wasn't in a void context. It was a scalar context :)

    That said, I'm still in two minds as to whether the 'map in a void context' problem is still a problem any more as (I believe) the main practical reason for not doing it was the inefficiency caused by building the return list only for it to be discarded. Since map now tests for context and doesn't bother building the list if in a void context, the reasons now seem esoteric/style related rather than practical. I agree that in most cases a for loop or modifier is better, but if you need to use a second modifier, map lends itself to the purpose. I wouldn't use it often, but I'm still undecided whether a blanket ban is called for.

    As for the File::Find and related calls. I have a (probably irrational) phobia about them, and it's not only to do with performance. I dislike their callback method of working, and their reliance upon global vars amongst other things. For example, the anonymous sub in your example is being called (many times) in a void context and the (unavoidable) return value is being discarded. How is this different from calling map in a void context?

    This really is "language lawyer" type stuff, but I seriously would appreciate your reaction/interpretation as I know you have made a point of studying many issues of this type.

    I'd also like to understand your (though that's not as bad on Win32) comment. How/why is this different for Win32 as compared to other OS's? I've racked my brains to see what you mean, but the significance escapes me?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller

      if you need to use a second modifier, map lends itself to the purpose.
      Hm? It takes a block, doesn't it? Not really comparable to a modifier.
      How is this different from calling map in a void context?

      Good question. Although if you go down that route, you could also say I'm calling find in void context, and the same about pretty much any prodedure call and basically every other line of code.

      In my point of view it's more of a conceptual question - the memory and performance concerns are additional, not the sole reason. I guess this is the mathematical part of my brain kicking in here - but to me, map is for mapping one set to another, and the fact that to do so it loops over the input is more of an implementation detail. On a dataflow architecture, as opposed to the Neumann machines Perl runs on, you could actually do the entire processing in large chunks at once.

      Ivory tower? You decide. (After all, my weakness is false hubris, as opposed to the false laziness most people have to overcome.)

      How/why is this different for Win32 as compared to other OS's?
      Traversal is easier to get right on Win32 systems. Besides some red herring special file types supported by more recent NTFS variants (which, to my knowledge, can be treated as plain files for most intents and purposes, anyway), there are only regular files and directories in a Win32 file system. On Unixoid systems, the situation is decidedly more complex with symlinks in the traversal equation. In fact it's even more tricky if you're collecting statistics on files, considering you have hardlinks, sparse files, fifos, device nodes, and possibly other more exotic beasts to deal with.

      Makeshifts last the longest.

        Sorry for the clumsy description. I was trying to say that if want to do

        some_statement for some_range while some_condition;
        which is perfectly legal and very useful syntax in a couple of languages I have used--including various DEC Basics which I think is where the modifier forms of if, for while & until were borrowed from-- but illegal in perl, then using
        map{ some_statement } some_range while some_condition;

        is a useful substitute.

        I take your point about map being conceptually different from a loop though, and I do try to avoid misusing it most of the time.

        Thanks for the explaination on the traversal thing. I always forget about the special file types. I can see how that routine could disappear up it's own er...stack if it encountered a circular symlink.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller