My fairly straightforward solution:

class ID3
  genre_list = <<-GENRES
Blues
... # snipped for brevity
Dance Hall
  GENRES

  GENRE_LIST = genre_list.split("\n")
  TAGS = [ :title, :artist, :album, :year, :comment, :track, :genre ]

  attr_accessor *TAGS

  def initialize(filename)
    id3 = File.open(filename) do |mp3|
      mp3.seek(-128, IO::SEEK_END)
      mp3.read
    end

    raise "No ID3 tags" if id3 !~ /^TAG/

    @title, @artist, @album, @year, @comment, @genre =
id3.unpack('xxxA30A30A30A4A30C1')
    @comment, @track = @comment.unpack('Z*@28C1') if @comment =~ /
\0.$/

    @genre = GENRE_LIST[@genre]
  end
end

if __FILE__ == $0
  id3 = ID3.new(ARGV.shift)
  ID3::TAGS.each do |tag|
    puts "#{tag.to_s.capitalize.rjust(8)}: #{id3.send(tag)}"
  end
end