in reply to Why does each() always re-evaluate its argument?

It's not each , but the %{...} doing reevaluation.

each expects a hash (or array with "newer" perls).

The %{} does dereferencing of the enclosed expression, which needs to be evaluated.

There is no way to tell for %{} if and why the result should be cached.

Update

To elaborate further, each is not a loop construct like foreach

It's more like a method operating on the hash, with no clear entry point.

Think %hash->each() and you can call each anytime outside while.

Update

You may rather want to take a look at this newer (5.36 experimental) syntax:

use experimental "for_list"; foreach my ($key, $value) (%hash) { # iterate over the hash # The hash is immediately copied to a flat list before the loop # starts. The list contains copies of keys but aliases of values. # This is the same behaviour as for $var (%hash) {...} }

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

  • Comment on Re: Why does each() always re-evaluate its argument? (Updated x2 - experimental "for_list" )
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Why does each() always re-evaluate its argument? (Updated x2 - experimental "for_list" )
by eyepopslikeamosquito (Archbishop) on Dec 06, 2023 at 23:30 UTC
      > but, sadly, did not run appreciably faster

      experimental "for_list" solves so many issues of each , that I'm already very happy if it's not slower.

      It's elegant, orthogonal and intuitive, and I hope the experimental phase will be a success.

      This benchmarks claims it to be much faster, but we all know how tough it is to write reasonable benchmarks which don't compare apples with oranges.

      Actually I'm surprised that copying large hashes into a list can even compete with the built-in iterator-counter of perl hashes used by 'each'.

      The implemention must be very clever. Or the overhead will only show with much larger hashes.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

        Actually I'm surprised that copying large hashes into a list can compete with the built-in iterator of perl hashes.

        1) There's no copying, and 2) it uses the built-in iterator.

        When we say "returns a list", we simply mean "returns zero or more scalars". It's not a data structure. You don't copy into a list since there's no such thing. We're talking about pushing pointers onto the stack. Which is exactly what keys, each or any other approach would have to do as well. There's no extra work here, so it shouldn't be surprising that it's not any slower.

Re^2: Why does each() always re-evaluate its argument? (Updated x2 - experimental "for_list" )
by Anonymous Monk on Dec 06, 2023 at 15:42 UTC