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

I am writing a quick subroutine to grab a list of files in a directory and return it as an array to be used in a select list for CGI::FormBuilder. I cannot seem to get the array to populate itself, even though I have searched through this simple test program I have written and it runs without errors, just does not print anything. Any help appreciated.
#!/usr/bin/perl use strict; my $dir = '/home/music'; my @mp3 = getSongs($dir); foreach my $song (@mp3) { print "$song\n"; } sub getSongs { my $dir = @_; use Carp; my @files; if (-d $dir) { opendir(MP3, $dir) || croak("Cannot open directory: $d +ir"); @files = readdir(MP3); closedir(MP3); } return @files; }
use strict; use CGI;

Replies are listed 'Best First'.
Re: subroutine array empty
by merlyn (Sage) on Dec 08, 2007 at 22:40 UTC
    my $dir = @_;
    That's most likely setting $dir to "1" (scalar context applied), and then skipping the rest of the subroutine because you don't have a directory named "1".
Re: subroutine array empty
by graff (Chancellor) on Dec 09, 2007 at 01:02 UTC
    I am writing a quick subroutine to grab a list of files in a directory and return it as an array...

    Just a side note: since the caller knows which directory is supposed to be scanned (and should also know that it's looking only for files whose names match "*.mp3" or something to that effect), there's no need for a subroutine call.

    The code that would call your subroutine could just do this instead:

    my @mp3files = <$path/*.mp3>;
    (assuming that $path is what would have been passed when calling your subroutine). That use of angle brackets in perl is referred to as a "file glob".
      Thank you so much for your quick replies. I knew it had to be something so simple I was messing up. I've been using CPAN modules so much writing my own subs has gotten rusty... That file glob is great and just what I needed, so simple. I'm going to strip off the directory name using some regexp's and then I'm good to go.
      use strict; use CGI;
Re: subroutine array empty
by mwah (Hermit) on Dec 08, 2007 at 22:50 UTC

    The error in your code has been already pointed out by merlyn and somebody else (how fast are these people ;-), but I'd like to add a more "idiomatic" version of your code. You should return mp3 files only (if you are after them ;-) ...

    #!/usr/bin/perl use strict; use warnings; use Carp; my $dir = '/home/musc'; my @mp3 = getSongs( $dir ); for my $song (@mp3) { print "$song\n"; } sub getSongs { my $dir = shift; my @files; if( -d $dir ) { opendir(my $dirhandle, $dir) or croak "$dir $!"; @files = grep /\.mp3$/, readdir $dirhandle; closedir $dirhandle } else { carp "don't know about $dir\n" } return @files; }

    Regards

    mwa

Re: subroutine array empty
by Anonymous Monk on Dec 08, 2007 at 22:41 UTC
    instead of

    sub getSongs { my $dir = @_; # INCORRECT: assigns @_ in SCALAR context ... } # end of subroutine definition

    try

    my ($dir) = @_; # assign @_ in list context