Pretty much every perl program written uses this idiom:
{
open(my $fh, '>>', $filename) || die "you lose";
print $fh $blah;
}
However, I don't want to die, I want to just skip the print. So I write:
{
print "you lose\n" unless (open(my $fh, '>>', $filename) and print $fh $blah);
}
and get "Can't use an undefined value as a symbol reference at ./o.pl line 5" for my trouble.
Removing the my (bad form) eliminates this error, as does:
{
my $fh;
print "you lose\n" unless (open($fh, '>>', $filename) and print $fh $blah);
}
but why?
Why, in the broken code, doesn't $fh
exist from open(my $fh...
to the close of the block (the }
)?
Here's an example of how lexical scoping works in JavaScript. var a = 10 var func = function (){ var b = 20; console. log("a and b is accessible (outer):", a, b); var innerFunc= function (){ var c = 30; console. log("a and b and c is accessible (inner):", a, b, c); } innerFunc(); return; } func(); console.
Lexical scope means that in a nested group of functions, the inner functions have access to the variables and other resources of their parent scope. This means that the child's functions are lexically bound to the execution context of their parents. Lexical scope is sometimes also referred to as static scope.
Lexical scope means that an object's (memory) scope will that where it (i.e., the object) was defined. Let's take a function "f()", for instance. A function has an inner scope and an outer scope. In a lexically scoped language (eg, Python), the outer scope of " f() " will be the scope where the function was defined.
What is Lexical Scope in JavaScript? Lexical scope is the definition area of an expression. In other words, an item's lexical scope is the place in which the item got created.
The my
doesn't take effect until the end of the statement.
For that same reason, my $x = $x
won't see the new $x
on the right hand side of the statement. It'll see the old $x
.
For example
use strict;
use warnings;
my $x = 42;
{
my $x = $x + 1;
print "inside, x = $x\n";
}
print "outside, x = $x\n";
This prints:
inside, x = 43
outside, x = 42
Your open
statement is roughly equivalent to the inner my
statement above. If you had $fh
declared in the outer scope, surprising fun would happen: You'd probably end up printing to the wrong file.
You may prefer
{
open(my $fh, '>>', $filename) || warn "you lose";
print $fh $blah if $fh->opened;
}
Of course you can also remove the warn
if you wish.
If your Perl 5 is older than version 14 then you will need to add
use IO::File
to the header of your code.
If you add strict
and warnings
to your program, you would get much more useful error messages:
use strict;
use warnings;
{
my $filename = "test.txt";
print "you lose\n" unless (open(my $fh, '>>', $filename)
and print {$fh} $blah);
}
__END__
Global symbol "$fh" requires explicit package name at test.pl line 6.
Global symbol "$blah" requires explicit package name at test.pl line 6.
Execution of test.pl aborted due to compilation errors.
The problem being that you can't declare and use a lexical variable in the same statement. $fh
will only be available after the line with the open
on it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With