luxgladius has asked for the wisdom of the Perl Monks concerning the following question:

Here's the output of an actual debug session. Can anybody explain this?
DB<10> p $#l 27 DB<11> p $#F 23 DB<12> p max($#l, $#F) 23 DB<13> p max(27,23) 27 DB<14> p 0+$#l 27 DB<15> p max(0+$#l, $#F) 27 DB<16> p max($#l, 0+$#F) 23
So the second-to-last line tells me the solution, but I have no clue what the actual problem is. For what it's worth, I'm using 64-bit Activestate Perl 5.20.

Edit: The max is from List::Util.

Replies are listed 'Best First'.
Re: Max of 23 and 27 is 23?
by ikegami (Patriarch) on Jul 02, 2015 at 19:57 UTC

    $#a returns a magical value in lvalue contexts. (It used to always returns a magical value, but this was optimized.)

    $ perl -MDevel::Peek -e'@a=qw( a b c ); sub { Dump($_[0]) }->( $#a );' SV = PVMG(0x1d36630) at 0x1cfcfd0 REFCNT = 1 FLAGS = (GMG,SMG) IV = 0 NV = 0 PV = 0 MAGIC = 0x1cf6ab0 MG_VIRTUAL = &PL_vtbl_arylen MG_TYPE = PERL_MAGIC_arylen(#) MG_OBJ = 0x1d07d10

    The behaviour you observe is a missing SvGETMAGIC(sv) to handle such scalars.

    use strict; use warnings; use List::Util qw( max ); use Variable::Magic qw( cast wizard ); # Make $x a magical variable that always returns 5. cast(my($x), wizard( get => sub { ${ $_[0] } = 5 }, ) ); $x = 3; if ($ARGV[0]) { no warnings 'void'; 0+$x } print('max($x, 4)=', max($x, 4), "\n"); print('$x=', $x, "\n");
    $ perl a.pl 0 max($x, 4)=4 $x=5 $ perl a.pl 1 max($x, 4)=5 $x=5
      The behaviour you observe is a missing SvGETMAGIC­(sv) to handle such scalars.

      Which is pretty much to be expected with the vast majority of XS code. Which is one reason why I almost never use List::Util routines. Must use XS for "speed!". Correctness, well, that doesn't matter quite as much.

      - tye        

        > Which is one reason why I almost never use List::Util routines. Must use XS for "speed!". Correctness, well, that doesn't matter quite as much. The authors care about correctness. However, they cannot fix bugs that they are not informed of.
Re: Max of 23 and 27 is 23?
by roboticus (Chancellor) on Jul 02, 2015 at 17:39 UTC

    luxgladius:

    It depends on how max is defined. FYI: min and max aren't built-in perl functions, so I'd start out with finding where it's coming from, and review the docs/source.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Sorry, it's List::Util 'max'.
Re: Max of 23 and 27 is 23?
by toolic (Bishop) on Jul 02, 2015 at 17:55 UTC
      Yes, it's List::Util max, and no, it was causing a bug where my list was being shortened in a map when I continued it to keep growing.

        So ... how (code please) was the "list being shortened in a map when [you] continued it to keep growing"?

Re: Max of 23 and 27 is 23?
by BrowserUk (Patriarch) on Jul 02, 2015 at 17:38 UTC
Re: Max of 23 and 27 is 23?
by Anonymous Monk on Jul 02, 2015 at 18:07 UTC

    Nothing odd here (perl 5.16.2 x86_64-linux, List::Util 1.35) ...

    DB<2> use List::Util 'max' DB<3> p max( 1 , 4 ) 4 DB<4> @p = ( 1 .. 5 ) DB<5> @q = ( 1 .. 11 ) DB<6> p $#p , $#q 410 DB<7> p max( $#p , $#q ) 10 DB<8> p max( 0+$#p , $#q ) 10
Re: Max of 23 and 27 is 23?
by Laurent_R (Canon) on Jul 02, 2015 at 19:56 UTC
    Hi,

    I tried to reproduce exactly your scenario, but I do not get any weird result:

    DB<1> @L = 0..27; # use @L rather than @l for more clarity (avoid m +istaking 1 and l) DB<2> p $#L; 27 DB<3> @F = 0..23; DB<4> p $#F; 23 DB<5> use List::Util 'max'; DB<6> p max($#L, $#F); 27
    Perhaps you should show how @l and @F are populating, although I fail to see what it could be at this point.

    My Perl version:

    perl 5, version 14, subversion 4 (v5.14.4)