in reply to Re: Re: Adding and Deleting Upload File name and File
in thread Adding and Deleting Upload File name and File

<cheek tongue="1">Your reply is correct, but your example isn't quite right</cheek>

I missed the qw which would indeed mean that the other '@lists' would be treated as strings but your example will yield a valid hash (no warning) since you have an even number of elements in the list:

my %test = ( '@song_titles' => '@song_files' );
   larryk                                          
perl -le "s,,reverse killer,e,y,rifle,lycra,,print"
Will code for food - looking for work - London - CV

Replies are listed 'Best First'.
Re: Re: Re: Re: Adding and Deleting Upload File name and File
by blakem (Monsignor) on Dec 04, 2001 at 00:43 UTC
    Just to clarify (and yes, I know we're way off in left field here....) the warning I was speaking of is thrown by the qw() code whenever it gets passed a comma (or #). From perlop:
    qw/STRING/
    ...
    A common mistake is to try to separate the words with comma or to put comments into a multi-line "qw"-string. For this reason, the "use warnings" pragma and the -w switch (that is, the "$^W" variable) produces warnings if the STRING contains the "," or the "#" character.
    % perl -we 'qw(@song_titles, @song_files)' Possible attempt to separate words with commas at -e line 1. [snip void context errors]
    On a side note, I should have realized that you just misread the qw. A quick /msg would have probably been a better response than the node I posted.... ;-)

    -Blake

Re: Re: Re: Re: Adding and Deleting Upload File name and File
by lex2001 (Sexton) on Dec 05, 2001 at 14:24 UTC
    thanks for the info. This is what I've got to work so far.
    # brings in arrays song_title and song_files &song_list; &file_list; #works by single elements my %test = ($song_titles[0], $song_files[0], $song_titles[1], $song_files[1]); foreach my $key (keys %test) { print qq[<br> Delete this File: $key <INPUT TYPE="checkbox" NAME=" +files" VALUE="$test{$key}">\n]; }
    Whatever is selected is then passed on to another subroutine that takes the value of "file" and deletes the file
    # check for tainted data my $files = $q->param( "files") || error( $q, "couldn't read File valu +e"); $files =~ /^([\/.\w.]+)$/; # The "untainted" file is now in $1 $files = $1; die "Bad filename" unless $files; foreach ($files){ unlink($_); }
    However I still can't figure out how I would delete the song title that goes with the song file. How could I also pass the value of the key (song_title) along with the song file? also I tried doing
    my %test = (@song_titles, @song_files);
    however, it printed out the first key right (song_title) but the next key contained the song file as the key and so on ... thanks in advance...
      If you want to delete a song based on the filename, one way of doing it is to go through the songs comparing the filename to the list to delete:
      # i renamed %test to %songs for sanity's sake for my $song_title (keys %songs) { my $song_file = $songs{$song_title}; if (grep $_ eq $song_file, @{$q->param('files')) { delete $song{$song_title}; unlink $song_file; } }
      You say you also tried my %test = (@song_titles, @song_files); which just strings the two lists together but because a hash takes pairs of elements you found that the pairings were incorrect. This can be resolved with my initial example (see above post) of @songs{@song_titles} = @song_files;.

      The thing with hashes is that the keys are all unique so to me it would make more sense if you used the filename (including path) as the key and the title (which there may be more than one instance of) as the value - this also removes your need to iterate through the songs to find the one to delete. Just an idea to make it work for you instead of the other way around.

      Hope this helps,

         larryk                                          
      perl -le "s,,reverse killer,e,y,rifle,lycra,,print"
      Will code for food - looking for work - London - CV
      
        Thank you for your patience and info. I got your example to work:
        @songs{@song_titles} = @song_files;
        This would place the @song_files elements as keys and the elements of @song_titles would be linked to these keys, correct? What confuses me is how it looks. It seems like it should be coded like this - since I want to make a hash
        %songs{@song_titles} = @song_files;
        moving to the deletion code that you entered above. I have been storing the song titles in a file. So if I delete one I could then print out all of the remaining values in the hash and overwrite the file correct? thanks...