This node falls below the community's threshold of quality. You may see it by logging in.

Replies are listed 'Best First'.
Re: mp3 collection renamer
by abstracts (Hermit) on Apr 28, 2002 at 08:50 UTC
    Time for code review ;)
    ########################################################### ### not gonna complain about strict, for whatever reason use MP3::Info; die "Must use parameters and seperator\n (SEPERATOR ARTIST TITLE YEAR +ALBUM GENRE COMMENT)" unless @ARGV; $sep=shift; @tokens=@ARGV; while(<*.mp3>) # while is wrong as you move files around, # should be for (grep /\.mp3$/i, <*>) # to insure getting files like "bla.MP3" ### indent your code! { my $tag=get_mp3tag($_) or (push(@errors,"No tag for $_\n") and nex +t); $nn=''; ### now you're using <space><sep><space> as a separator ### I wanted <sep> only. for $i (@tokens){$nn.=$tag->{$i}." $sep ";} my $z=rindex($nn,$sep); my $len=length $sep; substr($nn,$z,$len+1,''); chop $nn; $nn.='.mp3'; ### the last 6 lines should've been something like: ### $nn = join($sep, map $tag->{$_}, @tokens) . ".mp3"; ### and this is not my personal preferrence, but a more ### readable, straight to the point, honest to god statement print "Renamed $_ to $nn \n" if rename $_,$nn; ### where is my error check? } print "\n\n"; print @errors;
    And one more final thing which is more important than all of the above blabbering: do "perl name.pl '-' ARTIST" and wonder why all your artists suddenly have one song each.
    Or worse: Watch all your mp3s reduced to a singleton ".mp3" as you forget to pass args other than the sep!!.

    Hope this helps!!

Re: mp3 collection renamer
by boo_radley (Parson) on Apr 28, 2002 at 18:20 UTC
    abstracts' comments are spot on -- I'd like to reiterate 2 things, however.
    Firstly :
    for $i (@tokens){$nn.=$tag->{$i}." $sep ";} my $z=rindex($nn,$sep); my $len=length $sep; substr($nn,$z,$len+1,''); chop $nn; $nn.='.mp3';
    This is valid, but klunky perl.
    As I just went through the process of working with my own MP3 collection, I recommend using the tag object in hash form (I eventually went to tagged because I was rewriting id3v2 tags, but that's another story entirely). This is probably frowned upon by OOP purists, but we're all friends here. Here's a short example comparing the two methods.
    use MP3::Info; use strict; # # what's boo_radley listening to? # in CODE tag friendly format :) # my $fn = 'F:\Warlock Pinchers\Deadly Kung Fu Action '. '_ Pinch a Loaf\Warlock Pinchers - ' . 'Deadly Kung Fu Action _ Pinch a Loaf '. '- 06 - Black in Black.mp3'; my $tag=get_mp3tag($fn) || die "unable to get tag."; # tags to incorporate into new filename my @tokens = qw (ARTIST TITLE ALBUM GENRE); my $sep ="-"; my $nn; # from buu's script. # for my $i (@tokens){$nn.=$$tag{$i}." $sep "} my $z=rindex($nn,$sep); my $len=length $sep; substr($nn,$z,$len+1,''); chop $nn; $nn.='.mp3'; output the labors of our work print "\n$nn\n"; #using the $tag object as a hash (in hash slice form!) print join (" - ", @$tag{@tokens}),".mp3";
    If this isn't clear, any time an object uses a hash to store data, you can (usually, unless the module author was clever) access that hash by typecasting the instantiation of that object into a hash.
    Well, what does that mean? it means that if we have a $tag object, we can treat it like a simple hash like so : %$tag.
    OK. We've just reduced 6 lines of code to 1; that's a pretty good deal. There's less to troubleshoot, comment and the meaning of the code becomes clearer.

    Secondly : print "Renamed $_ to $nn \n" if rename $_,$nn; This is terrible! When renaming files, you should always check to see if the file exists beforehand!
    Always! Well, usually, and certainly in this case. I don't want to have to re-rip a cd because, this script renamed 32 mp3s to "WARLOCK PINCHERS.mp3" after only inputting the artist on the command line!
    I like to use unless in these cases, when I'm expecting (but still not sure!) that the file will not already exist.
    unless (-e $fn) { print "Renamed $_ to $nn \n" if rename $_,$nn } else { # for example ... push(@errors,"Tried to rename $_ to $nn, file exists\n") }


    Those are my concerns. Overall, I don't think this is entirely a bad script; it's probably one that you hacked together after saying "my mp3 collection, it's a damn mess!", and whipped together something immediately useful to you. Whenever you share things on perlmonks, it becomes a more public thing, though, and just as you pretty up to go out on the town, you should pretty up your code when you show it off on perlmonks. Comment things excessively. Your script requires command line parameters? Think about using Getopt::Long, or at least checking for a sane number of params. Did you examine a particular algorithm, found it lacking and developed a new strategy for the same task? Say so in your comments. When you're done with the script, go back and say,"What can I improve? What does not inherently make sense to me that I can change?".The quality and nature of your coding will improve when you start to actively think about it.
      Nice code review. Hopefully BUU will learn from it.

      But a minor pedantic point:

      If this isn't clear, any time an object uses a hash to store data, you can (usually, unless the module author was clever) access that hash by typecasting the instantiation of that object into a hash.

      I'm guessing that the above was just poor choice of words but just in case a newbie reads it I wanted to clear up what appears to be a bit of confusion.

      What you really mean is that any time an objects underlying data type is a hash then it can be manipulated just like a reference to a normal hash, ( there is no casting involved).  In fact due to the fact that object types in perl are orthogonal from the their data type (despite what ref() says) this statement can be generalized to say that an object reference can always be treated exactly the same as a reference to the underlying data type.  The clever bit only means that the author has used an underlying datatype (I'm guessing you meant CODE refs) that prevents introspection.

      Anyway, as I said good review.

      Yves / DeMerphq
      ---
      Writing a good benchmark isnt as easy as it might look.

    A reply falls below the community's threshold of quality. You may see it by logging in.