Tips on User Defined Variables


#1

I want to join the chorus of acclaim from other MP3tag users and
say that MP3Tag is a great program. As a professional programmer
with 22 years experience, I would be proud to have written MP3Tag myself.

I had to learn the hard way some things about MP3Tag's user-defined variables,
so I want to share my discoveries in hopes that others might benefit.

In brief, I learned that the scoping rules for user-defined variables
in MP3tag are a little different from the other programming
languages I'm familiar with.

I discovered this while I was trying to write an export script that
would generate a list of artists and their albums, with the total
number of albums at the end of the list.

The list was supposed to look like this:

1 10,000 Maniacs Hope Chest
2 10,000 Maniacs MTV Unplugged
3 A Drop in the Gray Certain Sculptures
...
1001 Yes Big Generator
1002 Yes YesSongs
Number of Albums: 1002

My first script attempt always displayed zero for the total number of albums.
The first script looked like this:

$put(cnt, 0)
$loop(%artist%)
$loop(%album%,1)

  $puts(cnt,$add($get(cnt),1))     
  $get(cnt) %artist% %album% 
  $loopend()

$loopend()
Number of Albums: $get(cnt)

Here's the script again, only this time with comments based
on how I believe user defined variables actually work.

$put(cnt, 0)
$loop(%artist%)
$loop(%album%,1)

  <!-- Because the $puts command below is in a loop, it 
       creates a new instance of cnt (instance 2) 
       Incrementing this instance does not affect the 
       contents of instance one -->
  $puts(cnt,$add($get(cnt),1))     
  $get(cnt) %artist% %album% 
  $loopend()

$loopend()

Number of Albums: $get(cnt)

What I didn't grok at first is that a referencing a variable in
a loop causes a new variable with the same name to be created. The
new variable hides the original variable within the loop. When
the loop ends, the second variable no longer hides the original variable.

Another subtlety I didn't anticipate is that variables created
in a loop continue to exist outside the loop and retain their value.

So, to get the total number of albums I had to remove the
first call to $put. This allowed the cnt variable that was
created in the loop to be visible outside the loop.

$loop(%artist%)
$loop(%album%,1)

  $puts(cnt,$add($get(cnt),1))
  $get(cnt) %artist% %album% 
  $loopend()

$loopend()
Number of Albums: $get(cnt)

If I've misunderstood how user-defined variables work, I hope
someone will correct my mistake.

Regards,
Al


#2

I think you've discovered for yourself one of the design flaws of Mp3tag's scripting system.
I mentioned the same thing some time ago in the german section 'Mp3tag Forums > Mp3tag - Deutsch > Bugs' but did not receive any answer yet.
Benutzerdefinierte Variable nicht sichtbar in Loop
I wish Florian to have some time to make this part of the scripting language more clear.

DD.20070413.1406


Warning: $if executes regardless of conditional!