LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Can't call method "title" on undefined title in Perl script (https://www.linuxquestions.org/questions/programming-9/cant-call-method-title-on-undefined-title-in-perl-script-396858/)

scuzzman 12-27-2005 09:33 AM

Can't call method "title" on undefined title in Perl script
 
I'm writing a short Perl script to rename a directory full of MP3 files and re-write some of their ID3 tags using the MP3::Tag module, but I'm having some trouble with it. Whenever I try to run it, I get this error:
Code:

[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$ ~/fixid3.pl
Will every file in this directory have the same album and artist header (y/n)? y
What is the title of the album? Thug Motivation 101

Who is the artist? Young Jeezy

Filename: track_01.mp3
What is the track name? Go Crazy - Remix
Can't call method "title" on an undefined value at /home/scuzzy/fixid3.pl line 51, <STDIN> line 4.

This is the Perl script I'm running:
Code:

#!/usr/bin/perl
# fixid3.pl - Perl script to write MP3 ID3 tags to files
# Fields are title, ARTIST, ALBUM, YEAR, COMMENT, GENRE

# load the ID3 module
use MP3::Tag;

# get the filesname(s)
# We'll just use all files in the directory:
@filenames = <*.mp3>; # This glob gets all mp3 files in current dir

print "Will every file in this directory have the same ";
print "album and artist header (y/n)? ";
chomp ( $same_album_artist = <STDIN> );
if ( $same_album_artist == "y" ) {
  print "What is the title of the album? ";
  chomp ( $album = <STDIN> );
  print "\n";
  print "Who is the artist? ";
  chomp ( $artist = <STDIN> );
  print "\n";
  foreach (@filenames) { # since the album and artist are the same, just change song titles
    print "Filename: $_\n";
    $file = $_;
    &fix_id3($album, $artist, $file);
  }
} elsif ($same_album_artist == "n") {
  foreach (@filenames) { # ask album and artist on each song
    print "Filename: $_\n";
    $file = $_;
    print "What is the title of the album? ";
    chomp ( $album = <STDIN> );
    print "\n";
    print "Who is the artist? ";
    chomp ( $artist = <STDIN> );
    print "\n";
    &fix_id3($album, $artist, $file);
  }
} else {
  die "Unrecognized entry.\n";
}

sub fix_id3 {
# Here's where the magic is done
  $album = $_[0];
  $artist = $_[1];
  $file = $_[2];
  print "What is the track name? ";
  chomp ( $title = <STDIN> );
  $mp3 = MP3::Tag->new($file); # Creates new object
  $mp3->{ID3v1}->title("$title"); # adds element title
  $mp3->{ID3v1}->artist("$artist"); # adds element artist
  $mp3->{ID3v1}->album("$album"); # adds element album
  $mp3->{ID3v1}->write_tag(); # writes the tags
  $mp3->close(); # close the file
  # we'll also rename the files
  $oldname = "\"$file\"";
  $newname = "\"$artist - ${title}.mp3\"";
  rename $oldname, $newname;

  print "\n";
}

Is there anything I can do to figure out why this is detecting an undefined value, even though everything should be properly defined?
Edit: I have just tried it with and without the quotes on these lines (in red) and yielded the same results:
Quote:

$mp3->{ID3v1}->title("$title"); # adds element title
$mp3->{ID3v1}->artist("$artist"); # adds element artist
$mp3->{ID3v1}->album("$album"); # adds element album

wrj 12-27-2005 11:03 AM

The error you're getting means that you are trying to call your methods (title being the first one) on an undefined object. I don't think you can access ID3v1 methods like that. You need to use the get_tags() method first to fetch all the tags the mp3 object has access to and then call it directly via the MP3::Tag::ID3v1

I think it will work if you add this after your new() call:

$mp3->get_tags();

unless (exists $mp3->{ID3v1}) {
# handle error ...
}

$id3v1 = $mp3->{ID3v1};
$id3v1->title($title);


Hope that helps

scuzzman 12-27-2005 12:15 PM

It's still not working, but now I at least have a clue why. This is the new segment of code:
Code:

  $mp3 = MP3::Tag->new($file); # Creates new object
  $mp3 -> get_tags();
  unless (exists $mp3->{ID3v1}) {
    die "Unable to read ID3 tags from file.\n";
  }
  $id3v1 = $mp3 -> {ID3V1};
  $id3v1 -> title( "$title" ); # adds element title

These are the errors from the console:
Code:

[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$ ~/fixid3.pl
Will every file in this directory have the same album and artist header (y/n)? y
What is the title of the album? Thug Motivation 101

Who is the artist? Young Jeezy

Filename: track_01.mp3
What is the track name? Go Crazy - Remix
Unable to read ID3 tags from file.

But what could be causing it to be unable to read the ID3 tags? Perhaps because they do not yet exist? If that's the case, then why can I not write them (to make them exist)?

wrj 12-27-2005 12:37 PM

Hmm ... how about dumping out the result of get_tags() and see what we actually get.

Code:

# add this to the top of your code
use Data::Dumper;

# add this somewhere in your function
$tags = [];
$tags = $mp3->get_tags;
print Dumper($tags)

Let me know what tags are available for your file.

scuzzman 12-27-2005 01:40 PM

OK - This is the current code snippet:
Code:

  print "What is the track name? ";
  chomp ( $title = <STDIN> );
  $mp3 = MP3::Tag->new($file); # Creates new object
  ##ADDED DEBUG
  $tags = [];
  $tags = $mp3->get_tags;
  print Dumper($tags);
  ##END DEBUG
  $mp3 -> get_tags();
  unless (exists $mp3->{ID3v1}) {
    die "Unable to read ID3 tags from file.\n";
  }

And this is the output:
Code:

[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$ ~/fixid3.pl           
Will every file in this directory have the same album and artist header (y/n)? y
What is the title of the album? Thug Motivation 101

Who is the artist? Young Jeezy

Filename: track_01.mp3
What is the track name? Go Crazy - Remix
$VAR1 = 2;
Unable to read ID3 tags from file.
[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$


wrj 12-27-2005 03:07 PM

Sorry I didn't realize get_tags just returns a list of strings.

Pleasse try the code snippet below and look at my comments for an explanation.

Code:


# wrap the object constructor call in an eval to
# make sure we catch any weird errors and object was
# created ok

eval {
  $mp3 = MP3::Tag->new($file);    # Creates new object
};

# make sure object was created ok
if ($@) {
  die qq{Error crating MP3 object, $@};
}

print qq{ MP3 Object created ok\n.};

# fetch list of tags
@tags = $mp3->get_tags();
print qq{tags\n}, Dumper(\@tags);

# no need to call get_tags again ...

# make sure ID3v1 is one ofthe choices on the list
# also make sure you have a little v not ID3V1 ... I
# know that's silly but I saw it in one off your earlier
# posts.

unless ( exists $mp3->{ID3v1} ) {
  die "Unable to read ID3 tags from file.\n";
}

$id3v1 = $mp3->{ID3v1};

# ready to set element title ... the double quotes should
# really be omitted since you are passing a variable not a
# straight string ... but it may not make a diff
$id3v1->title("$title");        # adds element title

Pardon me for any syntax errors, I don't have a computer I can test this on. Let me know how it works out.

scuzzman 12-27-2005 07:52 PM

Still not working... I'm pretty sure I understand most of the code, and it looks as though it should function (when the Dump is removed that is...). This is the current fix_id3 subroutine:
Code:

sub fix_id3 {
  # Here's where the magic is done
  $album = $_[0];
  $artist = $_[1];
  $file = $_[2];
  print "What is the track name? ";
  chomp ( $title = <STDIN> );
  # wrap the object constructor call in an eval to
  # make sure we catch any weird errors and object was
  # created ok
  eval {
    $mp3 = MP3::Tag->new($file);    # Creates new object
  };
  # make sure object was created ok
  if ($@) {
    die qq{Error crating MP3 object, $@};
  }
  print qq{ MP3 Object created ok.\n};
  # fetch list of tags
  @tags = $mp3->get_tags();
  print qq{tags\n}, Dumper(\@tags);

  unless ( exists $mp3->{ID3v1} ) {
    die "Unable to read ID3 tags from file.\n";
  }
  $id3v1 = $mp3->{ID3v1};
  # ready to set element title ... the double quotes should
  # really be omitted since you are passing a variable not a
  # straight string ... but it may not make a diff
  $id3v1->title("$title");        # adds element title
  $id3v1 -> artist( "$artist" ); # adds element artist
  $id3v1 -> album( "$album" ); # adds element album
  $id3v1 -> write_tag(); # writes the tags
  $mp3->close(); # close the file
  # we'll also rename the files
  $oldname = "$file";
  $newname = "$artist_-_${title}.mp3";
  rename $oldname, $newname;

  print "\n";
}

And this is the output from the console:
Code:

[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$ ~/fixid3.pl
Will every file in this directory have the same album and artist header (y/n)? y
What is the title of the album? Thug Motivation 101

Who is the artist? Young Jeezy

Filename: track_01.mp3
What is the track name? Go Crazy - Remix
 MP3 Object created ok
.tags
$VAR1 = [
          'ParseData',
          'LastResort'
        ];
Unable to read ID3 tags from file.
[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$

Although, I don't understand the use of 'qq' - is that kind of like 'qw'?

wrj 12-27-2005 08:22 PM

qq is double quotes. The difference is that qq will interpret any variables for you unlike q.

For some reason the file you're using only has 'ParseData' and 'LastResort' available.
That's why any references to $mp3->{ID3v1} are undefined.

I copied the script and ran it on my computer with one of my mp3 files and it worked.

This is the output:
Code:

(host: waldemar)  (user: waldemar)  (time= 21:09:06)
 > ~ $ ./test.pl
Will every file in this directory have the same album and artist header (y/n)? yWhat is the title of the album? foo

Who is the artist? bar

Filename: bignic.mp3
What is the track name? baz
 MP3 Object created ok
.tags
$VAR1 = [
          'ParseData',
          'ID3v2',
          'ID3v1',
          'LastResort'
        ];
done!

I didn't change anything else so the only difference is the file being used. I don't know much about mp3's so I don't know why only those 2 tags are limited for your mp3-object-file. Maybe you can try and find out why your mp3 file doesn't have ID3v1? I looked over the perldoc briefly and it looks like ID3v1 and ID3v2 are the only ones that support reading and writing. You might be able to just create those tags.

From the perldoc
Code:

# create a new tag
$mp3->new_tag("ID3v2");
$mp3->{ID3v2}->add_frame("TALB", "Album title");
$mp3->{ID3v2}->write_tag

Let me know

scuzzman 12-27-2005 08:54 PM

I cannot thank you enough for you help :) And for once, I understand what was not working. Here is the fully working code:
Code:

#!/usr/bin/perl
# fixid3.pl - Perl script to write MP3 ID3 tags to files
# Fields are title, ARTIST, ALBUM, YEAR, COMMENT, GENRE

# load the ID3 module
use MP3::Tag;

# get the filename(s)
# We'll just use all files in the directory:
@filenames = <*.mp3>; # This glob gets all mp3 files in current dir

print "Will every file in this directory have the same ";
print "album and artist header (y/n)? ";
chomp ( $same_album_artist = <STDIN> );
if ( $same_album_artist == "y" ) {
  print "What is the title of the album? ";
  chomp ( $album = <STDIN> );
  print "\n";
  print "Who is the artist? ";
  chomp ( $artist = <STDIN> );
  print "\n";
  foreach (@filenames) { # since the album and artist are the same, just change song titles
    print "Filename: $_\n";
    $file = $_;
    &fix_id3($album, $artist, $file);
  }
} elsif ($same_album_artist == "n") {
  foreach (@filenames) { # ask album and artist on each song
    print "Filename: $_\n";
    $file = $_;
    print "What is the title of the album? ";
    chomp ( $album = <STDIN> );
    print "\n";
    print "Who is the artist? ";
    chomp ( $artist = <STDIN> );
    print "\n";
    &fix_id3($album, $artist, $file);
  }
} else {
  die "Unrecognized entry.\n";
}

sub fix_id3 {
  # Here's where the magic is done
  $album = $_[0];
  $artist = $_[1];
  $file = $_[2];
  print "What is the track name? ";
  chomp ( $title = <STDIN> );
  # wrap the object constructor call in an eval to
  # make sure we catch any weird errors and object was
  # created ok
  eval {
    $mp3 = MP3::Tag->new($file);    # Creates new object
  };
  # Make sure the object was created OK
  if ($@) {
    die qq{Error creating MP3 object, $@}; # if not, die and tell us why
  }
  unless ( exists $mp3->{ID3v1} ) { # assure ID3v1 is a valid option
    $mp3 -> new_tag("ID3v1");
    $mp3 -> {ID3v1}->write_tag; # otherwise, create it
  }
  $mp3 -> {ID3v1} -> title("$title"); # adds element title
  $mp3 -> {ID3v1} -> artist("$artist"); # adds element artist
  $mp3 -> {ID3v1} -> album("$album"); # adds element album
  $mp3 -> {ID3v1} -> write_tag(); # writes the tags
  $mp3 -> close(); # close the file
  # we'll also rename the files
  $oldname = "$file";
  $newname = "${artist} - ${title}.mp3";
  rename $oldname, $newname;

  print "\n";
}

I think the problem was that all along the MP3 I was manipulating did not have any ID3 information - it simply needed the tags written :)
BTW: The extra variables $id3v1 and @tags were not needed - I've removed them. The code above works exactly as planned :D

scuzzman 12-30-2005 03:53 AM

As this is a learning exercise, I've been slowly adding more and more functionality to the script. Right now, I'm trying to add the functionality to verify the ID3's before rewriting them - but the function isn't running. This is the code:
Code:

#!/usr/bin/perl
# fixid3.pl - Perl script to verify and write MP3 ID3 tags to files
# Fields are TITLE, ARTIST, ALBUM, GENRE

# sub-routine definitions:
#  &get_id3: retrieves ID3 information from user
#  &show_id3: shows ID3 information to user and verifies accuracy
#  &fix_id3: sets ID3 tags based on user input

# load the ID3 module
use MP3::Tag;

# get the filename(s)
# We'll just use all files in the directory:
@filenames = <*.mp3>; # This glob gets all mp3 files in current dir

print "Will every file in this directory have the same ";
print "album and artist header (y/n)? ";
chomp ( $same_album_artist = <STDIN> );
print "Would you like to verify the ID3 information for each processed file? ";
chomp ( $verify = <STDIN> );
if ( $verify == "y" ) {
  $same_album_artist = "n"; # force this to no so it reveals and checks the information
}
if ( $same_album_artist == "y" ) {
  foreach (@filenames) {
    print "Filename: $_\n";
    $file = $_;
    my ( $artist , $album , $genre ) = &get_id3(); # get ID3 information from the user
    &fix_id3($album, $artist, $genre, $file);
  }
} elsif ($same_album_artist == "n") {
  foreach (@filenames) {
    print "Filename: $_\n";
    $file = $_;
    if ( ($verify == "y") && !(&show_id3($file)) ) {
      my ( $artist , $album , $genre ) = &get_id3();
      &fix_id3($album, $artist, $genre, $file);
    }
    if ( $verify == "n" ) {
    my ( $artist , $album , $genre ) = &get_id3();
    &fix_id3($album, $artist, $genre, $file);
    }
  }
} else {
  die "Unrecognized entry.\n";
}

sub get_id3 {
  print "What is the title of the album? ";
  chomp ( $album = <STDIN> ); # album name
  print "\n";
  print "Who is the artist? ";
  chomp ( $artist = <STDIN> ); # artist name
  print "\n";
  print "What is the Genre? ";
  chomp ( $genre = <STDIN> ); # music genre
  print "\n";
  @id3_tags = ($artist, $album, $genre); # load input into array for return
  return @id3_tags;  # return array
}

sub show_id3 {
  $file = $_[0];
  eval {
    $mp3 = MP3::Tag->new($file);    # Creates new object
  };
  # Make sure the object was created OK
  if ($@) {
    die qq{Error creating MP3 object, $@}; # if not, die and tell us why
  }
  unless ( exists $mp3->{ID3v1} ) { # assure ID3 tags exist
    print "No ID3 Information!\n"; # If no, exit sub with FALSE
    return 0;
  }
  print "Current ID3 Information:\n";
  print "Title: ";
  print $mp3 -> {ID3v1} -> title(); # retrieve title
  print "\n";
  print "Artist: ";
  print $mp3 -> {ID3v1} -> artist(); # retrieve artist
  print "\n";
  print "Album: ";
  print $mp3 -> {ID3v1} -> album(); # retrieve album
  print "\n";
  print "Genre: ";
  print $mp3 -> {ID3v1} -> genre(); # retrieve genre
  print "\n";
  print "Is this information correct (y/n)? ";
  chomp ( $correct = <STDIN> );
  if ($correct == "y") {
    return 1; # return true - information correct, skip file
  } elsif ($correct == "n") {
    return 0; # return false and rewrite data
  } else {
    die qq{Incorrect Input!\n};
  }
  print "\n";
}

sub fix_id3 {
  # Here's where the magic is done
  $album = $_[0];
  $artist = $_[1];
  $genre = $_[2];
  $file = $_[3];
  print "What is the track name? ";
  chomp ( $title = <STDIN> );
  # wrap the object constructor call in an eval to
  # make sure we catch any weird errors and object was
  # created ok
  eval {
    $mp3 = MP3::Tag->new($file);    # Creates new object
  };
  # Make sure the object was created OK
  if ($@) {
    die qq{Error creating MP3 object, $@}; # if not, die and tell us why
  }
  unless ( exists $mp3->{ID3v1} ) { # assure ID3v1 is a valid option
    $mp3 -> new_tag("ID3v1");
    $mp3 -> {ID3v1}->write_tag; # otherwise, create it
  }
  $mp3 -> {ID3v1} -> title("$title"); # adds element title
  $mp3 -> {ID3v1} -> artist("$artist"); # adds element artist
  $mp3 -> {ID3v1} -> album("$album"); # adds element album
  $mp3 -> {ID3v1} -> genre("$genre"); # adds element genre
  $mp3 -> {ID3v1} -> write_tag(); # writes the tags
  $mp3 -> close(); # close the file
  # we'll also rename the files
  $oldname = "$file";
  $newname = "${artist} - ${title}.mp3";
  rename $oldname, $newname;

  print "\n";
}

The function that isn't running (even if the appropriate options are entered) is the &show_id3 function. I'm not able to see anything I'm doing incorrect, so could someone please give this a look-over for me?

wrj 12-30-2005 08:48 AM

You're welcome. I'm glad you got it working.

One thing I just noticed is that you're using "==" for your string comparison.
The comparison operator for strings is "eq" and "==" is for numeric values only. That may be causing the issue.

ifeatu 12-10-2009 10:13 PM

Same Error!! No Solution!
 
This is a great thread...I'm beginning to think that this issue is deeper than just a file without tags...I've been fighting the "Can't callmethod " " on undefined value..." error for the past few hours now and can't seem to get a handle on the issue. I actually created two files...one simply edits meta tags and the other takes the name of the actually mp3 and parses it into a foldername THEN edits the meta tag. My goal is to write a program that takes a directory full of uniformly formatted mp3s and parses the names into uniformly named folders and also edits the meta tag of each mp3 using the data collected from parsing the filename:

Here is the metatag part (the part relevant to this thread)

Code:

#!/usr/bin/perl
use MP3::Tag;
@filename = <*.mp3>;

foreach (@filename) {

$filename = $_;
#$filename = $ARGV[0]; # you could hard code this to

# Get existing tags
$mp3 = MP3::Tag->new($_);
# ($title, $track, $artist, $album, $comment, $year, $genre) = $mp3->autoinfo();

# print "$title \n $track \n $artist \n";

$mp3->get_tags; # read tags
 
#debug...
if (exists $mp3->{ID3v1}) { # print track information
    print "Filename: $filename\n";
    print "Artist: " . $mp3->{ID3v1}->artist . "\n";
    print "Title: " . $mp3->{ID3v1}->title . "\n";
    print "Album: " . $mp3->{ID3v1}->album . "\n";
    print "Year: " . $mp3->{ID3v1}->year . "\n";
    print "Genre: " . $mp3->{ID3v1}->genre . "\n";
    print "Track: " . $mp3->{ID3v1}->track. "\n";
}
if (exists $mp3->{ID3v2}) { # print track information
    print "Filename: $filename\n";
    print "Artist: " . $mp3->{ID3v2}->artist . "\n";
    print "Title: " . $mp3->{ID3v2}->title . "\n";
    print "Album: " . $mp3->{ID3v2}->album . "\n";
    print "Year: " . $mp3->{ID3v2}->year . "\n";
    print "Genre: " . $mp3->{ID3v2}->genre . "\n";
    print "Track: " . $mp3->{ID3v2}->track. "\n";
}

# $genre = foobar;
# $mp3->{ID3v2}->title("$title");
# $mp3->{ID3v2}->year("$year");
# $mp3->{ID3v2}->album("$album");
# $mp3->{ID3v2}->track("$track");
# $mp3->{ID3v2}->genre("$genre");


# write tags
# $mp3->{ID3v2}->write_tag();

I included the lines that I commented out to demonstrate what I'd eventually like to do...this code WORKED exactly how I want it to on ONE mp3 file...when I insert the code with EXACTLY the same syntax into the larger code I get that weird error!!!

Code:

#!/usr/bin/perl
use MP3::Tag;
$file = <*.mp3>;
# open(MASTERFILE, "$file") or die ("Could not open log file.");
# while (<MASTERFILE>) {
$file = $_;
@array = /(.*)_([0-9]{2})_([0-9]{4}).{0,1}_(.*)_(.*)(_side)s*_s*([12])(.*)/;
#print "scalar(@array) \n";
$nums = @array;

mkdir "@array[4]-@array[2]-@array[0]-@array[1]- @array[3] -BLH";

$i =0;
while ($i < $nums){
print "Array element $i is: @array[$i] \n";

$i ++;
}

$mp3 = MP3::Tag->new($_);

$mp3->get_tags; # read tags

$genre = foobar;
$comment = "This is a test";

$mp3->{ID3v2}->write_tag();

if (exists $mp3->{ID3v1}) { # print track information
    print "Filename: $filename\n";
    print "Artist: " . $mp3->{ID3v1}->artist . "\n";
    print "Title: " . $mp3->{ID3v1}->title . "\n";
    print "Album: " . $mp3->{ID3v1}->album . "\n";
    print "Year: " . $mp3->{ID3v1}->year . "\n";
    print "Genre: " . $mp3->{ID3v1}->genre . "\n";
    print "Track: " . $mp3->{ID3v1}->track. "\n";
}
if (exists $mp3->{ID3v2}) { # print track information
    print "Filename: $filename\n";
    print "Artist: " . $mp3->{ID3v2}->artist . "\n";
    print "Title: " . $mp3->{ID3v2}->title . "\n";
    print "Album: " . $mp3->{ID3v2}->album . "\n";
    print "Year: " . $mp3->{ID3v2}->year . "\n";
    print "Genre: " . $mp3->{ID3v2}->genre . "\n";
    print "Track: " . $mp3->{ID3v2}->track. "\n";
}


Error:

Code:

$ perl perlProg.pl
Can't call method "get_tags" on an undefined value at perlProg.pl line 22.


Sergei Steshenko 12-11-2009 04:40 AM

Quote:

Originally Posted by scuzzman (Post 2017213)
I'm writing a short Perl script to rename a directory full of MP3 files and re-write some of their ID3 tags using the MP3::Tag module, but I'm having some trouble with it. Whenever I try to run it, I get this error:
Code:

[scuzzy@slackdell /home/scuzzy/music/young_jeezy/unknown_disc]$ ~/fixid3.pl
Will every file in this directory have the same album and artist header (y/n)? y
What is the title of the album? Thug Motivation 101

Who is the artist? Young Jeezy

Filename: track_01.mp3
What is the track name? Go Crazy - Remix
Can't call method "title" on an undefined value at /home/scuzzy/fixid3.pl line 51, <STDIN> line 4.

This is the Perl script I'm running:
Code:

#!/usr/bin/perl
# fixid3.pl - Perl script to write MP3 ID3 tags to files
# Fields are title, ARTIST, ALBUM, YEAR, COMMENT, GENRE

# load the ID3 module
use MP3::Tag;

# get the filesname(s)
# We'll just use all files in the directory:
@filenames = <*.mp3>; # This glob gets all mp3 files in current dir

print "Will every file in this directory have the same ";
print "album and artist header (y/n)? ";
chomp ( $same_album_artist = <STDIN> );
if ( $same_album_artist == "y" ) {
  print "What is the title of the album? ";
  chomp ( $album = <STDIN> );
  print "\n";
  print "Who is the artist? ";
  chomp ( $artist = <STDIN> );
  print "\n";
  foreach (@filenames) { # since the album and artist are the same, just change song titles
    print "Filename: $_\n";
    $file = $_;
    &fix_id3($album, $artist, $file);
  }
} elsif ($same_album_artist == "n") {
  foreach (@filenames) { # ask album and artist on each song
    print "Filename: $_\n";
    $file = $_;
    print "What is the title of the album? ";
    chomp ( $album = <STDIN> );
    print "\n";
    print "Who is the artist? ";
    chomp ( $artist = <STDIN> );
    print "\n";
    &fix_id3($album, $artist, $file);
  }
} else {
  die "Unrecognized entry.\n";
}

sub fix_id3 {
# Here's where the magic is done
  $album = $_[0];
  $artist = $_[1];
  $file = $_[2];
  print "What is the track name? ";
  chomp ( $title = <STDIN> );
  $mp3 = MP3::Tag->new($file); # Creates new object
  $mp3->{ID3v1}->title("$title"); # adds element title
  $mp3->{ID3v1}->artist("$artist"); # adds element artist
  $mp3->{ID3v1}->album("$album"); # adds element album
  $mp3->{ID3v1}->write_tag(); # writes the tags
  $mp3->close(); # close the file
  # we'll also rename the files
  $oldname = "\"$file\"";
  $newname = "\"$artist - ${title}.mp3\"";
  rename $oldname, $newname;

  print "\n";
}

Is there anything I can do to figure out why this is detecting an undefined value, even though everything should be properly defined?
Edit: I have just tried it with and without the quotes on these lines (in red) and yielded the same results:

Just don't waste your and our time trying to debug Perl scripts not having

Code:

use strict;
use warnings;

in the very beginning. First put the the above pragmas, achieve compilation without errors and run without warnings, then debug proper.


All times are GMT -5. The time now is 04:23 AM.