Without remarking on the program logic or identifier naming convention, here's how that sub should look:
sub Save
{
my $DirName = 'WinLog';
DirCreator($DirName);
foreach (@arr)
{
my $Log_obj = Win32::EventLog->new($_, "");
my $FileName = "$_.evtx";
$Log_obj->Backup(".\\$DirName.\\$FileName");
given ($^E)
{
when ('') { print "Log Successfully saved.\n"; }
when (/already exists/) {
# ...
}
default { print "Error: $^E\n"; }
}
$Log_obj->Close; # see Win32::EventLog's docs
}
}
Here are some helpful hints.
You don't need to escape periods in strings or spaces in regexes. You don't have to preceed function calls with '&'. You don't have to quote variables containing strings if there's nothing else inside the quotes.
When you quoted "$Log_obj" and passed that to close(), you sent a human-readable string that resembles that object, but not the object itself. When you create lexical filehandles, they are closed automatically when the variable goes out of scope. Most importantly, though, $Log_obj is not a filehandle. You needed to do $Log_obj->Close;, which calls the Close method of Win32::EventLog in the context of that object, not the builtin close function.
Declare lexical variables (variables scoped to the inner-most block) with "my". When you use "our", you're declaring a variable in the symbol table, so other modules and packages can access it; if you're just looking to define a module that's scoped to a package, declare it outside of a sub (or other block), and it's accessible to all code in the package.
The Switch module is buggy and deprecated. In Perl 5.10 and later, do use feature 'switch'; to enable the given/when construct, as I illustrated. If you're using an earlier version of Perl, use if/else constructs or something lke for ($value) { if (/foo/) { bar(); next; } }.
By default, $\ will usually be undefined, so you'll want a newline at the end of a print, or you might suffer from buffering.
And don't forget strictures: "use strict; use warnings;". |