Variable declaration reset: Difference between revisions

→‎{{header|Raku}}: Add a Raku example
(→‎{{header|Raku}}: Add a Raku example)
Line 122:
5
</pre>
 
=={{header|Raku}}==
By default, Raku variables need a prefix sigil indicating the storage / interface, and a scope declarator to indicate the variables' accessibility. The vast majority of the time, variables are declared with a "my" scope declarator that constrains them the the present block and any enclosed sub blocks. When a 'my' variable is declared inside a loop (block), a new independent instance of the variable is instantiated every time through.
 
<lang perl6>my @s = 1, 2, 2, 3, 4, 4, 5;
loop (my $i = 0; $i < 7; $i += 1) {
my $curr = @s[$i];
my $prev;
if $i > 1 and $curr == $prev {
say $i;
}
$prev = $curr;
}</lang>
{{out|Yields}}
<pre>Use of uninitialized value of type Any in numeric context
in block <unit> at var.p6 line 5
Use of uninitialized value of type Any in numeric context
in block <unit> at var.p6 line 5
Use of uninitialized value of type Any in numeric context
in block <unit> at var.p6 line 5
Use of uninitialized value of type Any in numeric context
in block <unit> at var.p6 line 5
Use of uninitialized value of type Any in numeric context
in block <unit> at var.p6 line 5</pre>
 
Lots of warnings but nothing else. If we suppress the warnings:
 
<lang perl6>my @s = 1, 2, 2, 3, 4, 4, 5;
quietly loop (my $i = 0; $i < 7; $i += 1) {
my $curr = @s[$i];
my $prev;
if $i > 1 and $curr == $prev {
say $i;
}
$prev = $curr;
}</lang>
 
No output.
<pre></pre>
 
We can however, declare the variable with an "our" scope, which effectively makes it a package global. Still need to suppress the warning about an uninitialized variable, but it will return an answer.
 
<lang perl6>my @s = 1, 2, 2, 3, 4, 4, 5;
quietly loop (my $i = 0; $i < 7; $i += 1) {
my $curr = @s[$i];
our $prev;
if $i > 1 and $curr == $prev {
say $i;
}
$prev = $curr;
}</lang>
 
{{out|Yields}}
<pre>2
5</pre>
 
Use of 'our' scoping is discouraged except in a few very specific situations. It "works" (for some value of works), but pollutes the namespace. The 'our' variable will trample any other instance of a variable with that name anywhere in the program in any other scope.
 
A better solution is to declare a state variable. A 'state' variable is essentially scoped similar to a 'my' variable (visible only inside the block), but is persistent across calls.
 
No warnings generated.
 
<lang perl6>my @s = 1, 2, 2, 3, 4, 4, 5;
loop (my $i = 0; $i < 7; $i += 1) {
my $curr = @s[$i];
state $prev;
if $i > 1 and $curr == $prev {
say $i;
}
$prev = $curr;
}</lang>
 
{{out|Yields}}
<pre>2
5</pre>
 
If you really want to run fast and loose, and bypass all the protections Raku builds in, you can turn off strict scoping with a pragma. This is '''''heavily''''' discouraged. Anyone trying to release code with strictures turned off will receive some degree of side-eye... but just because something is a bad idea in general doesn't mean Raku forbids it. The Raku mindset is "Make it difficult make casual mistakes but make it possible to bypass those protections if you have the need."
 
No scope declarators at all. Every variable is a global. Bad idea. Do not do this casually.
<lang perl6>no strict;
@s = 1, 2, 2, 3, 4, 4, 5;
loop ($i = 0; $i < 7; $i += 1) {
$curr = @s[$i];
if $i > 1 and $curr == $prev {
say $i;
}
$prev = $curr;
}</lang>
 
{{out|Yields}}
<pre>2
5</pre>
 
=={{header|Visual Basic .NET}}==
10,333

edits