Global symbol “$fh” requires explicit package name (did you forget to declare “my $fh”?)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Global symbol “$fh” requires explicit package name (did you forget to declare “my $fh”?)



I glob the files in a directory (non-recursive) that have an extension of .srt, .ass, .ssa, .txt with:


my @subfiles = glob '*.srt *.txt *.ass *.ssa';



Then, to write the xml sub files for spumux I call:
WRITESUBXML(); which is as follows:


WRITESUBXML();


sub WRITESUBXML
foreach my $i (@subfiles)
$SUBXMl="/users/dragonzero29/.wine/drive_c/mvtmp/$subfiles[$i].xml";
open(my $fh, '>', $SUBXMl) or die "Could not open file $SUBXMl $!";
print $fh "<subpictures format="NTSC">n";
print $fh "<stream>n";
print $fh "<textsub filename="$subfiles[$i]"n";
print $fh "characterset="UTF-8"n";
print $fh "fontsize="28.0"n";
print $fh "font="/users/dragonzero29/.wine/drive_c/mvtmp/arial.ttf"n";
print $fh "fill-color="yellow"n";
print $fh "outline-color="LightGray"n";
print $fh "outline-thickness="2.0"n";
print $fh "horizontal-alignment="center"n";
print $fh "vertical-alignment="bottom"n";
print $fh "left-margin="60"n";
print $fh "right-margin="60"n";
print $fh "top-margin="20"n";
print $fh "bottom-margin="30"n";
print $fh "subtitle-fps="29.97"n";
print $fh "movie-fps="29.97"n";
print $fh "movie-width="720"n";
print $fh "movie-height="480"n";
print $fh "force="no"/>n";
print $fh "</stream>n";
print $fh "</subpictures>";
close($fh);




Then, later I call the function to write the final dvdauthor file with
WRITEAUTHORXML(); which contains:


WRITEAUTHORXML();


sub WRITEAUTHORXML



and when run it spits out:


syntax error at /users/dragonzero29/cm2dvd_v2.pl line 309, near "$LANg ="
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 312.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 313.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 314.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 315.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 316.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 317.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 318.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 319.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 320.
Global symbol "$fh" requires explicit package name (did you forget to declare "my $fh"?) at /users/dragonzero29/cm2dvd_v2.pl line 321.
syntax error at /users/dragonzero29/cm2dvd_v2.pl line 323, near "}"
/users/dragonzero29/cm2dvd_v2.pl has too many errors.



well the edits let me successfully compile the script and my dvd project script works all the way to iso creation but I notice the subtitle xml files were NOT even created so the final dvd has no subs...aargh :( pls help. Also here is the code used to generate the xml files, used with the above code


foreach my $i(0 .. $#subxmlfiles)
system("spumux -s0 -m dvd -P
"/users/dragonzero29/.wine/drive_c/mvtmp/$subxmlfiles[$i]" <
"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG" >
"/users/dragonzero29/.wine/drive_c/mvtmp/$MOVIe.MUXED.MPG"nn");



sorry for the mess I still don't understand how to put code from TextMate
into this space pls advise..





Please edit your question to properly format it, its current state makes it hard to read and impossible to know which one is line 309 as reported from your error message.
– Patrick Mevzek
Aug 10 at 17:17



309





I fixed your formatting, please examine the input markdown (use the edit link) to see what I did for future reference.
– Jim Garrison
Aug 10 at 17:23






Possible duplicate of Perl: Global Symbol Requires Explicit Package Name
– Jim Garrison
Aug 10 at 17:25





Also for future reference ALWAYS Google the error message before posting here.
– Jim Garrison
Aug 10 at 17:26





Always fix the earliest error first. In this case: syntax error at /users/dragonzero29/cm2dvd_v2.pl line 309, near "$LANg ="
– melpomene
Aug 10 at 18:35


syntax error at /users/dragonzero29/cm2dvd_v2.pl line 309, near "$LANg ="




2 Answers
2



If there is a syntax error, ignore all the other errors and deal with the syntax error first.



Syntax errors can often confuse perl as to what scope you are in; here, it is unable to parse the bad foreach my $LANg but does see the } and thinks it ends the sub. So everything following that doesn't have a lexical $fh.


foreach my $LANg


}


$fh





I am intentionally not addressing the specific syntax error here; I wanted a useful answer for people in general who get hung up on the flood of Global symbol errors telling them to redirect their focus
– ysth
Aug 10 at 19:05


Global symbol



This part is not syntaxically correct:


foreach my $LANg = grep(/^EN/ || /^ES/,@subfiles)
print $fh "<subpicture lang="$LANg"n";



You need to rewrite it at least to:


foreach my $LANg (grep(/^EN/ || /^ES/,@subfiles))
print $fh "<subpicture lang="$LANg"n";



But I would recommend instead:


foreach my $lang (grep /^(?:EN @subfiles)
print $fh "<subpicture lang="$lang"n";



Note that it may not logically do what you hope it does, if @subfiles is a list of filenames, the grep will return the ones which start with EN or ES (are they named like that? and you need to take into account if the paths contain directories or not) and then return the whole file name (not just what has been matched) to be in $lang. So $lang will never be just EN or ES but a whole file name. If you need to extract only part of the name, you can look after map, it is often a great companion to grep.


@subfiles


EN


ES


$lang


$lang


EN


ES


map


grep



And as @Borodin pointed out in comments, you have other various problems in the code, like your $i variable in foreach my $i (@subfiles) is not an index (0, 1, 2, etc.) but one element of @subfiles into which you are iterating with foreach, that is a filename, and hence $subnames[$i] will be a runtime error as $i is not an index (a numerical value).


$i


foreach my $i (@subfiles)


@subfiles


foreach


$subnames[$i]


$i



So make sure to add use strict; use warnings; on top of your script and debug your syntax and then runtime errors one by one.


use strict; use warnings;



There are many other generic improvements you could do too.
For example, have a look at "here-documents", on https://perldoc.perl.org/perlop.html#Quote-Like-Operators search for <<EOF.


<<EOF



This would allow you to replace for example:


print $fh "<vmgm />n";
print $fh "<titleset>n";
print $fh "<menus>n";
print $fh "<pgc>n";



by just:


print $fh <<'EOF';
<vmgm />
<titleset>
<menus>
<pgc>
EOF



This would simplify your code a lot, as you do not need to escape " there.


"



Further ideas:


$i


$LANg


$lang


&


<


>





I've down-voted your post because (again) it doesn't come close to answering the question. The variables $i, $j, and $k are recognised as indexes and are perfectly valid in context. In this case $i is a file path but is used only once, as an array index. There is much more wrong with the OP's code than you have described (it won't even compile) and offering it as a solution is disingenuous.
– Borodin
Aug 10 at 17:54



$i


$j


$k


$i





"The variables $i, $j, and $k are recognised as indexes and are perfectly valid in context." where did I say there are invalid? I just offered the suggestion that a better name could be found, that gives more semantic value. As for the rest, I do not believe this website should be used as a generic "bad code on input" -> "code all fixed for you on output" service. I replied specifically about the error given in the question (other error => other question), and provided various ideas on how to improve other stuff. You are free to dislike my way of doing things, but thanks for your comments.
– Patrick Mevzek
Aug 10 at 18:32






@Borodin and feel free to post a better answer if you dislike the ones that you see. I believe this to be a better way of handling the problem you see, as then everyone will see all possible answers and will be free to upvote/downvote any of them. Your comment unfortunately does not help me in any way to improve my solution (based on the "framework" I explained in previous comment), so I can not change anything but again you could provide another, better in your eyes, solution that fix all the defects you see elsewhere.
– Patrick Mevzek
Aug 10 at 18:35






great thanks for the input now, where can I get more practice and info with:
– armight29
Aug 10 at 19:13





with, as I was saying: (?:EN|ES) for grep?
– armight29
Aug 10 at 19:15


(?:EN|ES)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard