in reply to Re^4: local() for scalar file slurping
in thread local() for scalar file slurping

I think that you use twice the memory in the version where $foo is assigned the results of the do{} block because you have the memory for the return value of the do{} block and the memory for the contents of $foo in use at the same time, so that you can copy from one to the other. Both contain a full copy of the whole file.

In the version where $foo is assigned to from within the do{}, you just have the $foo variable to hold the whole file, since it is assigned to in chunks from the file buffer. There is no other space allocated to hold the contents returned by the do{} block because the value of the do{} is not assigned to anything. Thus only one copy of the whole file has to be held in memory at one time.

That's the way I read it anyway.

Replies are listed 'Best First'.
Re^6: local() for scalar file slurping
by diotalevi (Canon) on Jul 31, 2006 at 15:46 UTC

    That may be the case but it's wrong behaviour on the part of the interpreter. The value being returned should be marked as a temporary and should be able to be re-used by the next part of the expression. It shouldn't be copied. If it is, that's a bug. Perl is supposed to be good at this kind of thing.

    ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

      A bug? or lack of a feature?

      The temporary value in question is and array, potentially a very big array. It's not ready to pass up to the next level until it's all there. Yes one could pass it up a piece at a time, in a queue, like the unix shells do with pipes, but that brings the overhead of monitoring the (those) process(es), and distinguishing from the case where you want to collect everything together and then proceed.

      It is a good idea, and it's what lazily evaluated lists are about in Perl6, see Apolalypse 6. The neat thing there is that you can even assign a lazy list to a variable, and not have to deal with getting to the end of the list until you use it. (Just don't ask for it's length up front.)

        You're misundersanding. The entire value is stored at once in a temporary variable known only on a padlist. The next operation, the scalar assignment, should utterly consume the temporary value during its use instead of making a copy just for it's own purposes. There should only be one copy of the data during this entire process. This is a perl5 thing, not a perl6 thing. I'm only speaking about perl5 internals.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

Re^6: local() for scalar file slurping
by apotheon (Deacon) on Jul 29, 2006 at 23:25 UTC

    Ahh, that makes sense. I suppose I should have figured that out for myself. Silly me.

    print substr("Just another Perl hacker", 0, -2);
    - apotheon
    CopyWrite Chad Perrin

      Not silly in my book.

      The explanation makes sense when you move down a level of abstraction. When you're at the upper level of abstraction the outer assignment reads "assign these records to $foo via this do{} block". Some times we need a little nudge to move to a different level of abstraction. All of us do. The way I see it the need for the nudge is a feature, not a bug. It allows us to concentrate at one level with less distraction.

      They say time is nature's way of keeping everything from happening at once. I'd say abstraction is our way of keeping from seeing everything at once.