0

I want to convert my foreach loop to a sub routine sub mybits. I'm sure I am not calling this properly or for that matter setting it up as a sub.

What I want to do is return a value from the sub routine which is any one of three variables which i tested foreach part and am able to get data.

Got this mesg. I am using strict, warnings: Can't modify non-lvalue subroutine call

How do I call this sub routine to get either of my variables ($dir, $fname, $fsize)?

Code:

my $out;
mybits (my $dir)=$out;
print mybits($dir);
print "This is mybits: $out\n";


sub mybits 
{
    foreach my $file( @{ $data->{file} } )
    {
        #my( $dir, $fname );
        my( $dir, $fname, $fsize );
        if( $file->{path} =~ /^(.*)\/([^\/]+)$/ )
        {
            $dir = $1;
            $fname = $2;
            $fsize = $file->{size};
        }
        else
        {
            $dir = "";
            $fname = $file->{path};
        }
        #print "This is the DIRECTORY: $dir\n";
        #print "This is the FILE:      $fname\n";
        #print "This is the FILE SIZE: $fsize\n";
    }

}
6
  • 1
    Do you use strict and use warnings? Further, it doesn't appear as though mybits is returning anything. Also, why would you assign the value of mybits($dir) to an uninitialized scalar and then expect print mybits($dir) to produce anything? Commented Oct 5, 2011 at 20:26
  • yes, i edited my question with the mesg. thanks. Commented Oct 5, 2011 at 20:28
  • The error message means that you're trying to assign the return value of a subroutine to some other scalar. Please explain what you're trying to do. Commented Oct 5, 2011 at 20:30
  • For that matter, mybits doesn't even take any arguments, since you're not doing anything with @_ inside of mybits. Commented Oct 5, 2011 at 20:32
  • 1
    Also, you're calling $file as an element of the array @{$data->{file}}, but then you mention $file->{path}, which would indicate that $file is a hash reference.... Is $data->{file} an array reference of hash references? What is the structure of $data? Commented Oct 5, 2011 at 20:37

2 Answers 2

1

It is impossible to get at any of $dir, $fname, or $fsize in your subroutine as written, since their scope is limited to your subroutine (specifically to the foreach loop within your subroutine). You'll have to have your subroutine return these values. However, since these are used over and over again in a loop, you'll probably want to return all possible values. Perhaps something like:

sub mybits 
{
    my $return_dirs=[];
    my $return_fnames=[];
    my $return_fsizes=[];
    foreach my $file( @{ $data->{file} } )
    {
        #my( $dir, $fname );
        my( $dir, $fname, $fsize );
        if( $file->{path} =~ /^(.*)\/([^\/]+)$/ )
        {
            $dir = $1;
            $fname = $2;
            $fsize = $file->{size};
        }
        else
        {
            $dir = "";
            $fname = $file->{path};
        }
        #Put the relevant data into the array references that we'll return later.
        push @$return_dirs,$dir;
        push @$return_fnames,$fname;
        push @$return_fsizes,$fsize;
    }

return [$return_dirs,$return_fnames,$return_fsizes];
}

my $values=mybits();

foreach(@$values)
{
  print join(",",@$_) . "\n";
}

Note: All of this assumes that the rest of the code in mybits actually works correctly...given that the OP only provided some of the code (eg we have no idea what $data is), I can't guarantee that this is the case.

Sign up to request clarification or add additional context in comments.

4 Comments

thank for your reply. I am building off of my last question: stackoverflow.com/questions/7656290/…. This shows $data.
@cjd143SD - You're welcome. So, have you tried altering your subroutine as described above?
Yes, I am testing it. So if the values ($return_dirs, $return_fnames, $retrun_fsizes) are stored in my $values, is it possible to print out any one of them? Let's say I want to print only $return_dirs, how would i do that? thanks.
Each of $return_dirs,$return_fnames, and $return_fsizes are array references, and $values is a reference to the array whose elements are $return_dirs, $return_fnames, and $retrun_fsizes (respectively). So, since $return_dirs is the first element, you can just do the following: print join(",",@{$values->[0]}) . "\n". But before you do any of this, I'd really recommend reading through some introductory Perl books (eg Beginning Perl) or at least perldoc perlref so that you understand what you're doing.
1

This line:

mybits (my $dir)=$out;

tries to assign $out to the value returned by your subroutine. This is not possible, it's not a valid lvalue hence the error. What exactly you want to do?

1 Comment

It's even worse, since mybits doesn't have any arguments... My best guess is that the OP trying to get at the values of $dir defined inside of mybits (which, of course, is impossible, since the scope of $dir is inside of mybits), but I can't tell for certain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.