Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

foreach scope destroying array's when referenced! HELP!!

Status
Not open for further replies.

unholyangl

Programmer
Feb 14, 2006
10
US
What I've been writing is a module to process a string and execute code accordingly for a set of scripts i'm working on (ex: read data from sockets, hence making communication easier.) But heres my problem...

Heres actual code:

Code:
sub trim {
   my $str = shift;
   $str =~ s/^\s+//;
   $str =~ s/\s+$//;
   return $str;
}

$_cmds{'trim'} = sub { # Wrapper to support arrays
   my $val; my @ret;
   while ($val = shift) { push(@ret, trim($val)); }
   if ( @ret > 1 ) { return \@ret; } else { return shift @ret; }
};


Everything is working perfect (or so it seems) in my module, accept for the array references.
I am calling them from within a foreach loop using the next command to jump through.

For example:

Code:
         # Execute a statement?
         ( $ccmd eq ";" ) && do {
            @tarr = @{$parr} if $parr && $parr ne 'ARRAY'; # Check
            $parr = \@carr; # reset
            if ( @tarr ) {
               $ecmd = $cmds->{shift(@tarr)}; # Retrieve command reference
               $lcmd = &$ecmd(@tarr) if $ecmd; # Execute and store in $lcmd

               # This part is added to test....
               print("Returned from $ecmd: $lcmd\n");
               if ($lcmd =~ 'ARRAY') {
                  @tarr = @{$lcmd};
                  print("addr: $lcmd; count: ".@tarr."; stringified: @tarr;\n");
               }


               @tarr = (); # Empty the array
            }
         next; };


When the array is returned, everything works here... But once we goto the next loop block; heres some code:

Code:
         # Separator?
         ( $ccmd eq "," ) && do {

               # This part is added to test....
               if ($lcmd =~ 'ARRAY') {
                  @tarr = @{$lcmd};
                  print("addr: $lcmd; count: ".@tarr."; stringified: @tarr; -,,\n");
               }

            push(@carr, $lcmd); $lcmd = undef;
            $parr = \@carr;
         next; };


Then I get an error like the following:
Can't use string ("ARRAY(0x18322e4)") as an ARRAY ref while "strict refs" in use at mods/parse.pm line 66.

I turn off strict refs to do testing and the array just doesn't exist. My guess is it's getting cleared in the foreach scope. Can someone help me work out a fix for this? I need the routines to be able to pass array references back and forth to eachother... Or am I gonna need to apply a hack thats gonna slow execution speed and open doors for bugs?

HELP!! THX!
 
What sounds like is happening is that your array reference is getting stringified. "ARRAY(0x18322e4)" isn't actually an array reference, it's a string representation of that reference. If you want to know if a particular reference is an array, check the return value of ref.

I usually ran into this problem trying to make references keys to a hash, then pull the keys back out and expected them to act like references again. Hash keys are not just scalars, they're strings.

- Andrew
Text::Highlight - A language-neutral syntax highlighting module in Perl
also on SourceForge including demo
 
Any ideas on a fix? I'm sure it's something easy that I'm missing, but ya :-/

The routine returns like the following:
return \@ret;

It's asigned like the following:
$lcmd = &$ecmd(@tarr) if $ecmd;

And at this point it seems to be working, but then on the next foreach loop scope:
@tarr = @{$lcmd};

This is where the error comes up. Any suggestions?
 
Never mind, right after making that last post I remembered a few places where it may happen. At the end of the foreach loop, the following code was fuxin me up:

$lcmd .= $ccmd; # Collect all other data together

I changed it to:

$lcmd .= $ccmd if $ccmd; # Collect all other data together

It's working correctly now thx!
 
As long as you understand, b/c I don't think I do. That looks like you're appending a string value to a an array reference, which I can't imagine making any real sense.

And my point about ref was to change code like
Code:
$lcmd =~ 'ARRAY'
into
Code:
ref($lcmd) eq 'ARRAY'
as that's really what you're checking.

- Andrew
Text::Highlight - A language-neutral syntax highlighting module in Perl
also on SourceForge including demo
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top