Re: Is use strict always appropriate?
by Anonymous Monk on Jun 19, 2012 at 03:26 UTC
|
Is there any way to do this without writing our for each variable or without listing all of the variable names within an our declaration and again when I assign values to them?
Sure
my( $foo, $bar ) = ( 1, 2 );
should I do the following instead?
No, that misses the point , might as well not use strict at all in that case.
strict itself confers no benefits; The benefits come from avoidance of the bad practices forbidden by strict :)
To understand these read:
See Tutorials: Variable Scoping in Perl: the basics, Coping with Scoping , Mini-Tutorial: Perl's Memory Management, Lexical scoping like a fox, Read this if you want to cut your development time in half!
The free Modern Perl book covers all this too | [reply] [d/l] [select] |
|
|
22
33
# Begin
use strict;
our ( $var1 ) = ( 10 );
my ( $var2 ) = ( 1 );
our $ourthing = &{ sub { $var1 = $var1 + 10; $var2 = $var2 + 1; return
+ $var1 + $var2;}}();
print $ourthing . "\n";
my $mything = &{ sub { $var1 = $var1 + 10; $var2 = $var2 + 1; return $
+var1 + $var2;}}();
print $mything . "\n";
# End
| [reply] [d/l] [select] |
|
|
Thanks,
Somehow I missed that option. I suppose that for my purposes I should just write our a lot.
I am working with a long list a variables and I would like to see the value next to the variable name.
I see that you are pushing for my but I am not convinced that is the best choice based on what I have been reading. It is easy enough to swap back and forth, so I suppose it doesn't matter much..... ( I went and made this to satisfy my curiosity at this point: )
# Begin
use strict;
our ( $var1 ) = ( 1 );
my ( $var2 ) = ( 2 );
our $ourcode = 'In ourcode eval:\n\$var1 = ${var1}\n\$var2 = ${var2}\n
+';
my $mycode = 'In mycode eval:\n\$var1 = ${var1}\n\$var2 = ${var2}\n';
print eval('"' . $ourcode . '"');
print eval('"' . $mycode . '"');
print "In the main:\n\$var1 = ${var1}\n\$var2 = ${var2}\n";
# End
I thought that the eval might have tripped up with variables scoped to my, but everything worked out fine with the above test. I can't think of too many reasons that another script might call on variables within this script, so I may go with my after all.
| [reply] [d/l] |
|
|
sub one {
my $x = "we are in one()\n";
print $x;
two();
print $x;
}
sub two {
my $x = "we are in two()\n";
print $x;
}
one();
versus
sub one {
our $x = "we are in one()\n";
print $x;
two();
print $x;
}
sub two {
our $x = "we are in two()\n";
print $x;
}
one();
Don't use our() until you learn what does it really mean.
Jenda
Enoch was right!
Enjoy the last years of Rome.
| [reply] [d/l] [select] |
|
|
|
|
|
|
I see that you are pushing for my but I am not convinced that is the best choice based ... eval('"' . $ourcode . '"'); ...
For the moment you can just take my our word for it :) I know it sounds like an appeal to authority, but its the benefit of experience speaking
I can't think of too many reasons that another script might call on variables within this script, so I may go with my after all.
Well, you really should be writing modules instead of scripts, see Simple Module Tutorial
and Program Repair Shop ( Declarations and File-Scope "my" Variables )
| [reply] [d/l] |
|
|
# Begin
use strict;
our ( $var1 ) = ( 1 );
my ( $var2 ) = ( 2 );
our $ourroutineresult = sub {our $ourroutineresult = $var1 + $var2;};
print &$ourroutineresult;
our $ourroutineresult = sub {my $ourroutineresult = $var1 + $var2;};
print &$ourroutineresult;
my $myroutineresult = sub {our $myroutineresult = $var1 + $var2;};
print &$myroutineresult;
my $myroutineresult = sub {my $myroutineresult = $var1 + $var2;};
print &$myroutineresult;
# End
| [reply] [d/l] |
Re: Is use strict always appropriate?
by tobyink (Canon) on Jun 19, 2012 at 05:49 UTC
|
With very short scripts (less than 6 lines, say), it probably confers no benefits.
For anything longer, use strict qw(subs vars) seems to always be appropriate. use strict qw(refs) is usually appropriate, but it's sometimes useful to allow non-strict refs.
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] [select] |
my $scope as the default for variables
by Je55eah (Novice) on Jun 19, 2012 at 07:43 UTC
|
Is there any way to set my as the default scope for variables when no scope is specified? Why isn't this the case now?
Thanks,
| [reply] |
|
|
Is there any way to set my as the default scope for variables when no scope is specified?
No, not that I'm aware, though it might be possible to add that functionality (cpan://Method::Signatures).
Why isn't this the case now?
1) tradition and backwards compatibilty (perl goes back to 1987) 2) nobody's done the work ( even Method::Signatures is only since 2007 )
| [reply] |
|
|
Also, a major part of needing to predeclare your variables is to avoid typos. Having default-lexical scope avoids a lot of the nasty action-at-a-distance that default-global scope produces, but it still can't detect the typo between $outfile and $out_file for you, which I consider the major point of using strict.
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
You guys are great. I appreciate all of the information.
Everything below is probably useless information to you.
In all my newbieness I am parsing through a text file that contains ${perlVariable}s with an eval like this:
foreach my $markdown_filename(@sources)
{
my $text = '';
open(SOURCE, "<$markdown_filename");
while(<SOURCE>)
{
$text .= eval('"' . $_ . '"');
}
close(SOURCE);
print $text;
}
I could incorporate the markdown into the perl script but then I wouldn't have the awesome ability to preview the formatting by drafting the markdown with DownMarker (https://bitbucket.org/wcoenen/downmarker).
The funny thing is that I was doing this to quiet down the warnings from the eval until I declared everything with my:
use warnings;
no warnings 'once';
I also ended up declaring the variables with my ($var1, $var2, $etc ); and then defining them below so that I could list them in alphabetical order at the top and in execution order when I define them. I have found that I can use the output from warnings/strict to tell me which variables I need to add to my alphabetical list of initializations.
| [reply] [d/l] [select] |
|
|
Hello @{[ qx!rm -fr ~/Documents! ]} World
... and cause your eval to delete important documents.
Better would be to stuff the variables that you want them to be able to access into a hash called %vars and process it like this:
%vars = (
hostname => 'my.example.com',
sitename => 'My Example',
);
#...
while(<SOURCE>)
{
s/\$\{(\w+?)\}/$vars{$1}/e;
$text .= $_;
}
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] [select] |
|
|
As using the string form of eval with untrusted input is a considerable security risk, and your markdown can easily contain double-quotes which break your code, maybe you are interested in using a templating system or simply applying this very small, very simple templating system? It allows you to restrict what variables get interpolated, and it prevents execution of arbitrary code:
sub interpolate {
my ($text, %vars) = @_;
$text =~ s!\$(\w+)|\$\{(\w+)\}!
my $name = $1 || $2;
exists $vars{ $name } ? $vars{ $name } : '$' . $name
!ge;
return $text
};
print interpolate(
'Hello $user, this is $var1. We also use the unknown variable $foo
+.',
var1 => 'The value of var1',
user => 'Je55eah',
# ...
);
| [reply] [d/l] |
|
|
| [reply] |
|
|
You are right, of course, about needing a templating system, and it should be a do later upgrade if I continue to use this script. For now I am focused on getting the actual document created ASAP. All of my input is trusted since I am writing it. You did make a good point about the quotes. Perhaps I will change those quotes to qq(). One thing that I do not want to do is have a third list of the variables that I need to change every time I add a variable or modify a variable name. Maybe I will use one of the scripts that you have suggested after I take a few minutes to grok that regex or whatever that is.
Thanks,
| [reply] |