I recognize that reusable toplevel code. When I run your code, all I needed to do was
( in addition to use warnings; use strict; ) was to add a global my $tl

Then the code runs fine, with a warning that on subsequent invoking of the reusable toplevel $tl, the Text widget from the last invocation will be gone.

So just add a global my $tl;

The whole idea of the reusable toplevel was to prevent memory gains, and this code may be such a beast. Everytime you run the toplevel, the private Text widget it contained gets stuffed aside into no-man's land, where memory accumulates. The Text widget I included with that toplevel example, is not needed. If you do need a persistent Text widget, for that reusable toplevel, just make my $text; a global variable, rather than just scoped to the toplevel subroutine.