Bug in debugger (or my code): Bizarre copy of ARRAY...

Discussion in 'Perl Misc' started by vnick@freenet.de, Oct 4, 2005.

  1. Guest

    Hi,

    (before I start, sorry for the length of this posting)
    I have this code (test case):
    --------------------------------------------------------
    #!/usr/local/bin/perl

    use strict;
    use vars qw ($d %spec %spec_cc);

    # Nested Hash/Array hierarchy:
    %spec = (
    RIF_SOURCE_WIDTH => {
    FMT => {genrule => "0x20", },
    WIDTH => {genrule => "look_up(FMT)",
    FMT => {
    10 => "mul(ORIG_WIDTH,4)",
    20 => "sub(ORIG_WIDTH,1)",
    _OTHER_ => "sub(mul(int(div(ORIG_WIDTH,2)),2),1)",
    _RANGE_ => [0,3, "and(ORIG_WIDTH,~3)"], #
    },
    },
    },
    );

    ######################################################################
    # MAIN:

    print ">>> " . $spec{RIF_SOURCE_WIDTH}{WIDTH}{FMT}{_RANGE_} . "\n";
    local $d = 0;
    %spec_cc = ();
    &struct_copy (\%spec, \%spec_cc);
    print "### " . $spec_cc{RIF_SOURCE_WIDTH}{WIDTH}{FMT}{_RANGE_} . "\n";
    print "### " . $spec_cc{RIF_SOURCE_WIDTH}{WIDTH}{FMT}{_RANGE_}[2] .
    "\n";

    ######################################################################
    sub struct_copy {

    my ($oref, $cref) = @_;
    my $objkey; # indexing var.
    my $ret = 0; # Return value.
    $d++;

    if (ref($oref) eq "HASH") {
    foreach $objkey (keys(%$oref)) {
    printf "H-key($d): %-20s \t[$oref -> $cref]\n",$objkey;
    if (ref($$oref{$objkey}) eq "HASH") {
    $$cref{$objkey} = ({}); # Generate empty hash hierarchy.
    &struct_copy ($$oref{$objkey},$$cref{$objkey} );
    }
    elsif (ref($$oref{$objkey}) eq "ARRAY") {
    $$cref{$objkey} = ([]); # Generate empty array hierarchy.
    &struct_copy ($$oref{$objkey},$$cref{$objkey} );
    }
    elsif (ref($$oref{$objkey}) eq "SCALAR" || ref($$oref{$objkey})
    eq "") {
    $$cref{$objkey} = $$oref{$objkey};
    }
    else {
    warn "ERROR: Only deep hashes or arrays or a mix of them can be
    copied\n";
    $ret = 1;
    }
    }
    }
    elsif (ref($oref) eq "ARRAY") {
    for ($objkey = 0; $objkey <= $#{@$oref}; $objkey++) {
    printf "A_Ind($d): %-20s \t[$oref -> $cref]\n", $objkey;
    if (ref($$oref[$objkey]) eq "HASH") {
    $$cref[$objkey] = ({}); # Generate empty hash hierarchy.
    &struct_copy ($$oref[$objkey],$$cref[$objkey] );
    }
    elsif (ref($$oref[$objkey]) eq "ARRAY") {
    $$cref[$objkey] = ([]); # Generate empty array hierarchy.
    &struct_copy ($$oref[$objkey],$$cref[$objkey] );
    }
    elsif (ref($$oref[$objkey]) eq "SCALAR" || ref($$oref[$objkey])
    eq "") {
    $$cref[$objkey] = $$oref[$objkey];
    }
    else {
    warn "ERROR: Only deep hashes or arrays or a mix of them can be
    copied\n";
    $ret = 1;
    }
    }
    return $ret;
    }
    else {
    warn "ERROR: Object $$oref is neither array nor hash!\n";
    $ret = 1;
    }
    $d--;
    return $ret;
    }

    ---------------------------------------------------------------

    sub struct_copy is to copy any combination of Hashes and Arrays
    (probably obvious to most readers :).

    My problem is now that this piece of code works fine -
    but only as long as I do not use the debugger!

    Running the code without debugger gives:

    ----------------------------------------------------------------

    >>> ARRAY(0x4003f7fc)

    H-key(1): RIF_SOURCE_WIDTH [HASH(0x4006bec0) -> HASH(0x4006bee4)]
    H-key(2): WIDTH [HASH(0x4009b590) -> HASH(0x4009b5b4)]
    H-key(3): FMT [HASH(0x4009b560) -> HASH(0x4009b818)]
    H-key(4): _OTHER_ [HASH(0x4005d5c8) -> HASH(0x40058f2c)]
    H-key(4): _RANGE_ [HASH(0x4005d5c8) -> HASH(0x40058f2c)]
    A_Ind(5): 0 [ARRAY(0x4003f7fc) ->
    ARRAY(0x400591a8)]
    A_Ind(5): 1 [ARRAY(0x4003f7fc) ->
    ARRAY(0x400591a8)]
    A_Ind(5): 2 [ARRAY(0x4003f7fc) ->
    ARRAY(0x400591a8)]
    H-key(5): 10 [HASH(0x4005d5c8) -> HASH(0x40058f2c)]
    H-key(5): 20 [HASH(0x4005d5c8) -> HASH(0x40058f2c)]
    H-key(4): genrule [HASH(0x4009b560) -> HASH(0x4009b818)]
    H-key(3): FMT [HASH(0x4009b590) -> HASH(0x4009b5b4)]
    H-key(4): genrule [HASH(0x4003f6d0) -> HASH(0x40058f14)]
    ### ARRAY(0x400591a8)
    ### and(ORIG_WIDTH,~3)

    --------------------------------------------------------------

    After switching the debugger on:

    --------------------------------------------------------------

    Loading DB routines from perl5db.pl version 1.27
    Editor support available.

    Enter h or `h h' for help, or `man perldebug' for more help.

    main::(testtest.pl:7): %spec = (
    main::(testtest.pl:8): RIF_SOURCE_WIDTH => {
    DB<1> c
    >>> ARRAY(0x4003f5ec)

    H-key(1): RIF_SOURCE_WIDTH [HASH(0x402724d4) -> HASH(0x402724f8)]
    H-key(2): WIDTH [HASH(0x4027662c) -> HASH(0x40337d04)]
    H-key(3): FMT [HASH(0x4027605c) -> HASH(0x4031bc9c)]
    H-key(4): _OTHER_ [HASH(0x40275e34) -> HASH(0x4005fdec)]
    H-key(4): _RANGE_ [HASH(0x40275e34) -> HASH(0x4005fdec)]
    Bizarre copy of ARRAY in leave at testtest.pl line 65.
    at testtest.pl line 65
    main::struct_copy('ARRAY(0x4003f5ec)', 'ARRAY(0x4006008c)')
    called at testtest.pl line 53
    main::struct_copy('HASH(0x40275e34)', 'HASH(0x4005fdec)')
    called at testtest.pl line 49
    main::struct_copy('HASH(0x4027605c)', 'HASH(0x4031bc9c)')
    called at testtest.pl line 49
    main::struct_copy('HASH(0x4027662c)', 'HASH(0x40337d04)')
    called at testtest.pl line 49
    main::struct_copy('HASH(0x402724d4)', 'HASH(0x402724f8)')
    called at testtest.pl line 32
    Debugged program terminated. Use q to quit or R to restart,
    use O inhibit_exit to avoid stopping after program termination,
    h q, h R or h O to get additional info.
    DB<1>

    ---------------------------------------------------------------

    So the question is why Perl (5.8.5) only reports this bizarre error
    when I use the debugger?? Do I still have a bug in my code though it
    works and I do not see where it could be or is that a debugger bug?

    Any help appreciated - thanks!
    Volker
     
    , Oct 4, 2005
    #1
    1. Advertising

  2. Paul Lalli Guest

    wrote:
    > Hi,
    >
    > (before I start, sorry for the length of this posting)
    > I have this code (test case):
    > --------------------------------------------------------
    > #!/usr/local/bin/perl
    >
    > use strict;


    Why aren't you using warnings?

    > use vars qw ($d %spec %spec_cc);


    Why are you using global variables?
    Why are you using 'use vars' instead of 'our'?

    <snip>

    > local $d = 0;


    Why are you localizing global variables instead of declaring lexicals?

    > %spec_cc = ();
    > &struct_copy (\%spec, \%spec_cc);


    Why are you calling your subroutines with the ampersand?

    Your code looks very much like Perl 4. I would suggest you head to
    http://learn.perl.org and start learning Perl 5.

    > sub struct_copy is to copy any combination of Hashes and Arrays
    > (probably obvious to most readers :).


    Why are you reinventing the wheel? Take a look at Data::Dumper, or
    CPAN's Clone and Storable.

    > After switching the debugger on:


    > Bizarre copy of ARRAY in leave at testtest.pl line 65.
    > at testtest.pl line 65


    Did you go to line 65 to see if there's anything wrong? I did...

    > for ($objkey = 0; $objkey <= $#{@$oref}; $objkey++) {


    That should be $#{$oref}, not $#{@$oref}.

    Now, I have no idea why they syntax you used doesn't report an error or
    a warning, but fixing this line removes the error from the debugging
    run.

    .... and further examination reveals that Perl apparently allows both
    versions of this syntax:

    $ perl -le'my @foo=qw/a b c d/; print $#{@foo};'
    3
    $ perl -le'my @foo=qw/a b c d/; print $#{foo};'
    3

    That seems odd to me. I'd never seen the first version of this before
    this post.

    > So the question is why Perl (5.8.5) only reports this bizarre error
    > when I use the debugger??


    I have no idea about this either...

    > Do I still have a bug in my code though it works and I do not see where it
    > could be or is that a debugger bug?


    Hard to call it a "bug" when it doesn't appear to affect the
    functionality of the code, but I'd still say it's definately something
    that should be fixed...

    Paul Lalli
     
    Paul Lalli, Oct 4, 2005
    #2
    1. Advertising

  3. Guest

    Thanks, Paul...

    Paul Lalli wrote:

    > > Bizarre copy of ARRAY in leave at testtest.pl line 65.
    > > at testtest.pl line 65

    >
    > Did you go to line 65 to see if there's anything wrong? I did...
    >
    > > for ($objkey = 0; $objkey <= $#{@$oref}; $objkey++) {

    >
    > That should be $#{$oref}, not $#{@$oref}.


    Why? $# says that it should give the last index of an array but $oref
    is
    a reference whereas @$oref is the array. So why is that wrong?
    This is dereferencing the array reference, is it? And then taking the
    array to get its last index!?

    Volker
     
    , Oct 4, 2005
    #3
  4. Peter Scott Guest

    On Tue, 04 Oct 2005 04:46:36 -0700, wrote:
    > Bizarre copy of ARRAY in leave at testtest.pl line 65.

    [snip]
    > So the question is why Perl (5.8.5) only reports this bizarre error
    > when I use the debugger?? Do I still have a bug in my code though it
    > works and I do not see where it could be or is that a debugger bug?


    If you can reduce this to a *much* shorter example and demonstrate it on
    the latest version of perl, please report it to the Perl 5 Porters list.
    While bugs like this in the debugger are notoriously difficult to fix,
    the bug report will be accepted. It should be impossible to get this
    message by accident regardless of poor programming practices.

    --
    Peter Scott
    http://www.perlmedic.com/
    http://www.perldebugged.com/
     
    Peter Scott, Oct 4, 2005
    #4
  5. Paul Lalli Guest

    wrote:
    > > That should be $#{$oref}, not $#{@$oref}.

    >
    > Why? $# says that it should give the last index of an array but $oref
    > is a reference whereas @$oref is the array. So why is that wrong?
    > This is dereferencing the array reference, is it? And then taking the
    > array to get its last index!?


    $oref is the reference
    @{$oref} is the array itself
    ${$oref}[0] is the first element
    $#{$oref} is the last index.

    This all follows "Use Rule 1" from
    http://perldoc.perl.org/perlreftut.html#Using-References

    '$oref' is the name of the array @{$oref}, just as 'foo' is the name of
    the array @foo. To obtain the last index of an array, you prepend its
    name with the '$#' characters.

    As I said in my previous followup, it is clear that Perl does accept
    the alternate syntax of prepending $# to the entire array, including
    sigil (as in: $#@foo), but I have no idea why. (perldoc perldata,
    which discusses the $# syntax, certainly doesn't mention it).

    Paul Lalli
     
    Paul Lalli, Oct 4, 2005
    #5
  6. Paul Lalli Guest

    Peter Scott wrote:
    > On Tue, 04 Oct 2005 04:46:36 -0700, wrote:
    > > Bizarre copy of ARRAY in leave at testtest.pl line 65.

    > [snip]
    > > So the question is why Perl (5.8.5) only reports this bizarre error
    > > when I use the debugger?? Do I still have a bug in my code though it
    > > works and I do not see where it could be or is that a debugger bug?

    >
    > If you can reduce this to a *much* shorter example and demonstrate it on
    > the latest version of perl, please report it to the Perl 5 Porters list.
    > While bugs like this in the debugger are notoriously difficult to fix,
    > the bug report will be accepted. It should be impossible to get this
    > message by accident regardless of poor programming practices.


    #!/usr/bin/perl -d
    use strict;
    use warnings;

    my $i;
    my $aref = [1..10];
    for ($i=0; $i<=$#{@$aref}; $i++){
    print "$i: $aref->[$i]\n";
    }

    __END__

    $ ./clpm.pl
    Default die handler restored.

    Loading DB routines from perl5db.pl version 1.07
    Editor support available.

    Enter h or `h h' for help, or `man perldebug' for more help.

    main::(./clpm.pl:5): my $i;
    DB<1> c
    Bizarre copy of ARRAY in leave at ./clpm.pl line 7.
    Debugged program terminated. Use q to quit or R to restart,
    use O inhibit_exit to avoid stopping after program termination,
    h q, h R or h O to get additional info.
    DB<1>


    (I'll send this to the porters as well)

    Paul Lalli
     
    Paul Lalli, Oct 4, 2005
    #6
  7. Paul Lalli Guest

    Paul Lalli wrote:
    > Peter Scott wrote:
    > > If you can reduce this to a *much* shorter example

    >


    Previous program was not nearly as short as it could have been:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my $i;
    my @a = (1..10);

    my $last = $#{@a};
    print "Last index: $last\n";

    __END__


    Do note, however, that I am currently using 5.6.1. I'll test with a
    more recent version when I leave work tonight.

    Paul Lalli
     
    Paul Lalli, Oct 4, 2005
    #7
  8. Guest

    Paul Lalli wrote:
    >
    > $oref is the reference
    > @{$oref} is the array itself
    > ${$oref}[0] is the first element
    > $#{$oref} is the last index.
    >
    > This all follows "Use Rule 1" from
    > http://perldoc.perl.org/perlreftut.html#Using-References
    >
    > '$oref' is the name of the array @{$oref}, just as 'foo' is the name of
    > the array @foo. To obtain the last index of an array, you prepend its
    > name with the '$#' characters.


    If that is correct where is the difference then between a symbolic and
    a hard reference in Perl?


    Thanks again.
    Volker
     
    , Oct 4, 2005
    #8
  9. Paul Lalli wrote:
    > wrote:
    >>>That should be $#{$oref}, not $#{@$oref}.

    >>Why? $# says that it should give the last index of an array but $oref
    >>is a reference whereas @$oref is the array. So why is that wrong?
    >>This is dereferencing the array reference, is it? And then taking the
    >>array to get its last index!?

    >
    > $oref is the reference
    > @{$oref} is the array itself
    > ${$oref}[0] is the first element
    > $#{$oref} is the last index.
    >
    > This all follows "Use Rule 1" from
    > http://perldoc.perl.org/perlreftut.html#Using-References
    >
    > '$oref' is the name of the array @{$oref}, just as 'foo' is the name of
    > the array @foo. To obtain the last index of an array, you prepend its
    > name with the '$#' characters.
    >
    > As I said in my previous followup, it is clear that Perl does accept
    > the alternate syntax of prepending $# to the entire array, including
    > sigil (as in: $#@foo), but I have no idea why. (perldoc perldata,
    > which discusses the $# syntax, certainly doesn't mention it).


    Apparently sometimes @array and array are synonymous, probably some backwards
    compatibility thing.

    $ perl -le' @x = 3..9; print $#{@x}'
    6
    $ perl -le' @x = 3..9; print $#x'
    6
    $ perl -le' @x = 3..9; print shift( x )'
    3
    $ perl -le' @x = 3..9; print shift( @x )'
    3



    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Oct 4, 2005
    #9
  10. Paul Lalli Guest

    wrote:
    > Paul Lalli wrote:
    > >
    > > $oref is the reference
    > > @{$oref} is the array itself
    > > ${$oref}[0] is the first element
    > > $#{$oref} is the last index.
    > >
    > > This all follows "Use Rule 1" from
    > > http://perldoc.perl.org/perlreftut.html#Using-References
    > >
    > > '$oref' is the name of the array @{$oref}, just as 'foo' is the name of
    > > the array @foo. To obtain the last index of an array, you prepend its
    > > name with the '$#' characters.

    >
    > If that is correct where is the difference then between a symbolic and
    > a hard reference in Perl?


    .... what has any of this to do with symbolic vs hard references?

    #!/usr/bin/perl
    use strict '!refs';
    use warnings;

    our $foo = 'hello world';
    my $hard = \$foo;
    my $name = 'foo';
    my $soft = ${$name};

    print "Hard: $$hard\nSoft: $soft\n";

    __END__

    A hard reference is a variable that actually contains a reference to
    another variable. A soft (or 'symbolic') reference is a variable that
    contains the name of another variable.

    http://perldoc.perl.org/perlref.html#Symbolic-references

    Paul Lalli
     
    Paul Lalli, Oct 4, 2005
    #10
  11. Jeff Stampes Guest

    Paul Lalli wrote:
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my $i;
    > my @a = (1..10);
    >
    > my $last = $#{@a};
    > print "Last index: $last\n";
    >
    > __END__
    >
    >
    > Do note, however, that I am currently using 5.6.1. I'll test with a
    > more recent version when I leave work tonight.


    Confirmed on a more modern perl:

    This is perl, v5.8.6 built for i386-linux-thread-multi

    ~JEff
     
    Jeff Stampes, Oct 4, 2005
    #11
  12. Babacio Guest

    Jeff Stampes.

    > Confirmed on a more modern perl:
    >
    > This is perl, v5.8.6 built for i386-linux-thread-multi
    >

    Same symptom on:

    This is perl, v5.8.7 built for darwin-thread-multi-2level

    --
    Bé erre hue ixe eu elle, Bruxelles.
     
    Babacio, Oct 4, 2005
    #12
  13. Anno Siegel Guest

    John W. Krahn <> wrote in comp.lang.perl.misc:


    > $ perl -le' @x = 3..9; print shift( x )'

    3

    Yikes!

    It does give a syntax warning, however:

    $ perl -wle '@x = 3..9; print shift( x )'
    Unquoted string "x" may clash with future reserved word at -e line 1.
    Array @x missing the @ in argument 1 of shift() at -e line 1.
    3

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Oct 6, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. omission9
    Replies:
    3
    Views:
    344
    Ziaran
    Feb 23, 2004
  2. Joachim Fabini

    Bizarre copy of ARRAY

    Joachim Fabini, Oct 7, 2003, in forum: Perl Misc
    Replies:
    3
    Views:
    173
    Joachim Fabini
    Oct 7, 2003
  3. John
    Replies:
    0
    Views:
    96
  4. kj
    Replies:
    2
    Views:
    140
  5. Robert Oschler
    Replies:
    1
    Views:
    225
    Mcginkel
    Sep 5, 2005
Loading...

Share This Page