in reply to This "each" goes to endless loop each time...

The problem is evaluating e for each iteration of the while loop. If you make the ref assignment outside the loop things work as expected:

use warnings; use strict; my %env= %{e ()}; $|=1; while (my ($var, $val) = each %env) { print "(hash) $var=$val\n"; } my $ref = e (); while (my ($var,$val) = each %$ref) { print "(ref) $var=$val\n"; } sub e { my %result=(A=>1,B=>2); wantarray ? each %result : \%result; }

Prints:

(hash) A=1 (hash) B=2 (ref) A=1 (ref) B=2

As an aside: prototyping subs in Perl is only very occasionally required and should not be done as a matter of course. Likewise, calling subs using & is magical and should only be used when required.


Perl is environmentally friendly - it saves trees

Replies are listed 'Best First'.
Re^2: This "each" goes to endless loop each time...
by rovf (Priest) on Jun 19, 2008 at 11:27 UTC
    As an aside: prototyping subs in Perl is only very occasionally required and should not be done as a matter of course
    Well, maybe I misinterpreted perlsub which says It's probably best to prototype new functions as being a recommendation for prototypes. I know that the basic idea in prototypes is to provide a way to call subs like "builtin" ones, but I must admit that I already found more than one errors in my code, because Perl complained that my calling parameters don't match the prototype. Of course I know that it easy to bypass the prototype checking if I want to (but usually I don't want to).
    -- 
    Ronald Fischer <ynnor@mm.st>

      The full quote is "It's probably best to prototype new functions, not retrofit prototyping into older ones" with the strong implication that it only applies in the context of adding prototypes to old subs. It is followed by a brief explanation of why retrofitting should be avoided: "That's because you must be especially careful about silent impositions of differing list versus scalar contexts". And that is the crux of the problem - prototyped subs don't do what you expect in some situations and often lead to very hard to see and debug problems. It is unfortunate that so much space in the documentation is given to a feature that should have a large "Here be dragons" label on it.

      Note too that "the intent of this feature is primarily to let you define subroutines that work like built-in functions" could (and according to informed opinion: should) be read to mean the only time prototypes should be used is to emulate built in functions.

      Note too the final comment in the prototype section of the documentation: "This is all very powerful, of course, and should be used only in moderation to make the world a better place.".

      Much has been written about prototype at PerlMonks. Some of the following may be interesting: subroutine prototypes still bad?, The purpose of prototypes in perl subroutines, Considering Prototypes, Are prototypes evil? and many others.


      Perl is environmentally friendly - it saves trees
        Thanks for the clarification, and also for the link you provided (really enlightening material!).
        -- 
        Ronald Fischer <ynnor@mm.st>