any way to retrieve a circular reference value - perl

I wrote th following program to see feature called circular reference in perl.
my $foo = 100;
$foo = \$foo;
print "Value of foo is : ", $$foo, " " , $foo;
the output was:
Value of foo is : REF(0x21b632c) REF(0x21b632c)
but i was wondering where the value 100 gone can any one help me.or is it a memory leak?

The value 100 was overwritten. When you assign a value into a variable, it replaces the previous value.
my $foo = 100;
$foo = "a string here";
The value 100 has gone. The same thing happens in your code above. The only difference is what kind of value was put in there.

Related

Changes in CGI.pm function param() behavior? [duplicate]

I am a little confused as which way to test parameters. Here are two examples from source code posted below. First is this
if(!defined($DBHdl) || !defined($acct_no));
the way to test for undefined parameters?
Second, after assigning to a hashref
$ptMtrRecRef = $ptSelHdl->fetchrow_hashref;
is the best way to test for $ptMtrRecRef being defined to use
if(!$ptMtrRecRef)
or
if(!defined($ptMtrRecRef))?
###############################################################################
# Returns count of meters per account number.
# $PkNam -- package name discarded
# $DBHdl -- ICS database handle
# $acct_no -- water account number
sub mgbl_get_meter_count
{
my ($PkNam, $DBHdl, $acct_no) = #_;
die("mgbl_get_meter_count passed undef handles.\n")
if(!defined($DBHdl) || !defined($acct_no));
my $ptSelHdl;
my $ptMtrRecRef;
my $sql_statement =
"select count(*) from meter m where m.acct_no = ".$acct_no.";";
$ptSelHdl = $DBHdl->prepare($sql_statement);
die("Cannot prepare select count(*) from meter m\n")
if(!$ptSelHdl || !$ptSelHdl->execute);
$ptMtrRecRef = $ptSelHdl->fetchrow_hashref;
return $ptMtrRecRef;
}
$sth->fetchrow_hashref will either return undef or a reference to a hash. As such
if (defined($row))
and
if ($row)
are equivalent here. (undef is false, and reference is always true.) I opt for the simpler alternative.
Same idea for $dbh->prepare.
In the case of the code you posted, I would also do as ikegami said, and use the shorter form.
There are occasions when that isn't suitable, however, for example if a variable could have a legitimate value that would be treated as false if simply used in a true/false test. For example:
my $value = 0;
print "defined\n" if defined $value; # prints 'defined'
print "true\n" if $value; # does not print anything
Well , in perl script language, defined($a) is just a sub routine to test if $a is "undef",nothing else. So ,you will ask ,what is undef?
To be accurate, it is a perl subroutine ,the same as defined.But when it has no parameter, it can be considered as a perl-special scalar . For example , when you pop a value from an empty array ,it will return an undef.When you call subroutine "undef $b",then $b will become undef($b must be an left value),nothing else. Only in this case, defined($b) will return false.But if $c is an empty string like "" ,number zero ,or string "0" ,defined($c) will still return true;
But if you use a simple boolean expression instead of defined,it becomes totally different. A simple Boolean test will not distinguish among undef, zero, the empty string, and "0" .So , it absolutely depends on your pratical requirement when determining using defined() or just a boolean test.

Perl: what happens when we assign a constant value to a reference variable instead of address of a variable?

Example:
#! /usr/bin/perl -w
$$var=10;
print "Variable is containing $$var and is of type ". ref($$var)."\n";
Output:
$perl testRefVar.pl
Variable is containing 10 and is of type
Here the variable $$var is not referring to any other variable, but a constant. So is there any significance of prefixing a variable with '$$'?
This is the same as setting any other variable to 10, except that the access is indirect.
perl will autovivify an anonymous scalar variable and assign the reference to $var so that this action can be fulfilled. If you print out $var you will get something like SCALAR(0x3ecec4).
To do this explcitily you could write
my $temp;
my $var = \$temp;
$$var = 10;
which would assign 10 to the variable $temp.
If, instead, you set $var to a reference to a constant, like this
my $var = \99;
$$var = 10;
you would get the error message
Modification of a read-only value attempted
because in this case $var refers to a constant instead of a variable.
Here, $var is a a reference to a scalar, and $$var is the scalar itself. Unless your code specifically wants references, the indirection (requiring the use of two dollar signs when you want the actual scalar) is at the very least a cumbersome hassle.

When to use defined

I am a little confused as which way to test parameters. Here are two examples from source code posted below. First is this
if(!defined($DBHdl) || !defined($acct_no));
the way to test for undefined parameters?
Second, after assigning to a hashref
$ptMtrRecRef = $ptSelHdl->fetchrow_hashref;
is the best way to test for $ptMtrRecRef being defined to use
if(!$ptMtrRecRef)
or
if(!defined($ptMtrRecRef))?
###############################################################################
# Returns count of meters per account number.
# $PkNam -- package name discarded
# $DBHdl -- ICS database handle
# $acct_no -- water account number
sub mgbl_get_meter_count
{
my ($PkNam, $DBHdl, $acct_no) = #_;
die("mgbl_get_meter_count passed undef handles.\n")
if(!defined($DBHdl) || !defined($acct_no));
my $ptSelHdl;
my $ptMtrRecRef;
my $sql_statement =
"select count(*) from meter m where m.acct_no = ".$acct_no.";";
$ptSelHdl = $DBHdl->prepare($sql_statement);
die("Cannot prepare select count(*) from meter m\n")
if(!$ptSelHdl || !$ptSelHdl->execute);
$ptMtrRecRef = $ptSelHdl->fetchrow_hashref;
return $ptMtrRecRef;
}
$sth->fetchrow_hashref will either return undef or a reference to a hash. As such
if (defined($row))
and
if ($row)
are equivalent here. (undef is false, and reference is always true.) I opt for the simpler alternative.
Same idea for $dbh->prepare.
In the case of the code you posted, I would also do as ikegami said, and use the shorter form.
There are occasions when that isn't suitable, however, for example if a variable could have a legitimate value that would be treated as false if simply used in a true/false test. For example:
my $value = 0;
print "defined\n" if defined $value; # prints 'defined'
print "true\n" if $value; # does not print anything
Well , in perl script language, defined($a) is just a sub routine to test if $a is "undef",nothing else. So ,you will ask ,what is undef?
To be accurate, it is a perl subroutine ,the same as defined.But when it has no parameter, it can be considered as a perl-special scalar . For example , when you pop a value from an empty array ,it will return an undef.When you call subroutine "undef $b",then $b will become undef($b must be an left value),nothing else. Only in this case, defined($b) will return false.But if $c is an empty string like "" ,number zero ,or string "0" ,defined($c) will still return true;
But if you use a simple boolean expression instead of defined,it becomes totally different. A simple Boolean test will not distinguish among undef, zero, the empty string, and "0" .So , it absolutely depends on your pratical requirement when determining using defined() or just a boolean test.

Why does this Perl variable keep its value

What is the difference between the following two Perl variable declarations?
my $foo = 'bar' if 0;
my $baz;
$baz = 'qux' if 0;
The difference is significant when these appear at the top of a loop. For example:
use warnings;
use strict;
foreach my $n (0,1){
my $foo = 'bar' if 0;
print defined $foo ? "defined\n" : "undefined\n";
$foo = 'bar';
print defined $foo ? "defined\n" : "undefined\n";
}
print "==\n";
foreach my $m (0,1){
my $baz;
$baz = 'qux' if 0;
print defined $baz ? "defined\n" : "undefined\n";
$baz = 'qux';
print defined $baz ? "defined\n" : "undefined\n";
}
results in
undefined
defined
defined
defined
==
undefined
defined
undefined
defined
It seems that if 0 fails, so foo is never reinitialized to undef. In this case, how does it get declared in the first place?
First, note that my $foo = 'bar' if 0; is documented to be undefined behaviour, meaning it's allowed to do anything including crash. But I'll explain what happens anyway.
my $x has three documented effects:
It declares a symbol at compile-time.
It creates an new variable on execution.
It returns the new variable on execution.
In short, it's suppose to be like Java's Scalar x = new Scalar();, except it returns the variable if used in an expression.
But if it actually worked that way, the following would create 100 variables:
for (1..100) {
my $x = rand();
print "$x\n";
}
This would mean two or three memory allocations per loop iteration for the my alone! A very expensive prospect. Instead, Perl only creates one variable and clears it at the end of the scope. So in reality, my $x actually does the following:
It declares a symbol at compile-time.
It creates the variable at compile-time[1].
It puts a directive on the stack that will clear[2] the variable when the scope is exited.
It returns the new variable on execution.
As such, only one variable is ever created[2]. This is much more CPU-efficient than then creating one every time the scope is entered.
Now consider what happens if you execute a my conditionally, or never at all. By doing so, you are preventing it from placing the directive to clear the variable on the stack, so the variable never loses its value. Obviously, that's not meant to happen, so that's why my ... if ...; isn't allowed.
Some take advantage of the implementation as follows:
sub foo {
my $state if 0;
$state = 5 if !defined($state);
print "$state\n";
++$state;
}
foo(); # 5
foo(); # 6
foo(); # 7
But doing so requires ignoring the documentation forbidding it. The above can be achieved safely using
{
my $state = 5;
sub foo {
print "$state\n";
++$state;
}
}
or
use feature qw( state ); # Or: use 5.010;
sub foo {
state $state = 5;
print "$state\n";
++$state;
}
Notes:
"Variable" can mean a couple of things. I'm not sure which definition is accurate here, but it doesn't matter.
If anything but the sub itself holds a reference to the variable (REFCNT>1) or if variable contains an object, the directive replaces the variable with a new one (on scope exit) instead of clearing the existing one. This allows the following to work as it should:
my #a;
for (...) {
my $x = ...;
push #a, \$x;
}
See ikegami's better answer, probably above.
In the first example, you never define $foo inside the loop because of the conditional, so when you use it, you're referencing and then assigning a value to an implicitly declared global variable. Then, the second time through the loop that outside variable is already defined.
In the second example, $baz is defined inside the block each time the block is executed. So the second time through the loop it is a new, not yet defined, local variable.

Perl - What scopes/closures/environments are producing this behaviour?

Given a root directory I wish to identify the most shallow parent directory of any .svn directory and pom.xml .
To achieve this I defined the following function
use File::Find;
sub firstDirWithFileUnder {
$needle=#_[0];
my $result = 0;
sub wanted {
print "\twanted->result is '$result'\n";
my $dir = "${File::Find::dir}";
if ($_ eq $needle and ((not $result) or length($dir) < length($result))) {
$result=$dir;
print "Setting result: '$result'\n";
}
}
find(\&wanted, #_[1]);
print "Result: '$result'\n";
return $result;
}
..and call it thus:
$svnDir = firstDirWithFileUnder(".svn",$projPath);
print "\tIdentified svn dir:\n\t'$svnDir'\n";
$pomDir = firstDirWithFileUnder("pom.xml",$projPath);
print "\tIdentified pom.xml dir:\n\t'$pomDir'\n";
There are two situations which arise that I cannot explain:
When the search for a .svn is successful, the value of $result perceived inside the nested subroutine wanted persists into the next call of firstDirWithFileUnder. So when the pom search begins, although the line my $result = 0; still exists, the wanted subroutine sees its value as the return value from the last firstDirWithFileUnder call.
If the my $result = 0; line is commented out, then the function still executes properly. This means a) outer scope (firstDirWithFileUnder) can still see the $result variable to be able to return it, and b) print shows that wanted still sees $result value from last time, i.e. it seems to have formed a closure that's persisted beyond the first call of firstDirWithFileUnder.
Can somebody explain what's happening, and suggest how I can properly reset the value of $result to zero upon entering the outer scope?
Using warnings and then diagnostics yields this helpful information, including a solution:
Variable "$needle" will not stay shared at ----- line 12 (#1)
(W closure) An inner (nested) named subroutine is referencing a
lexical variable defined in an outer named subroutine.
When the inner subroutine is called, it will see the value of
the outer subroutine's variable as it was before and during the first
call to the outer subroutine; in this case, after the first call to the
outer subroutine is complete, the inner and outer subroutines will no
longer share a common value for the variable. In other words, the
variable will no longer be shared.
This problem can usually be solved by making the inner subroutine
anonymous, using the sub {} syntax. When inner anonymous subs that
reference variables in outer subroutines are created, they
are automatically rebound to the current values of such variables.
$result is lexically scoped, meaning a brand new variable is allocated every time you call &firstDirWithFileUnder.
sub wanted { ... } is a compile-time subroutine declaration, meaning it is compiled by the Perl interpreter one time and stored in your package's symbol table. Since it contains a reference to the lexically scoped $result variable, the subroutine definition that Perl saves will only refer to the first instance of $result. The second time you call &firstDirWithFileUnder and declare a new $result variable, this will be a completely different variable than the $result inside &wanted.
You'll want to change your sub wanted { ... } declaration to a lexically scoped, anonymous sub:
my $wanted = sub {
print "\twanted->result is '$result'\n";
...
};
and invoke File::Find::find as
find($wanted, $_[1])
Here, $wanted is a run-time declaration for a subroutine, and it gets redefined with the current reference to $result in every separate call to &firstDirWithFileUnder.
Update: This code snippet may prove instructive:
sub foo {
my $foo = 0; # lexical variable
$bar = 0; # global variable
sub compiletime {
print "compile foo is ", ++$foo, " ", \$foo, "\n";
print "compile bar is ", ++$bar, " ", \$bar, "\n";
}
my $runtime = sub {
print "runtime foo is ", ++$foo, " ", \$foo, "\n";
print "runtime bar is ", ++$bar, " ", \$bar, "\n";
};
&compiletime;
&$runtime;
print "----------------\n";
push #baz, \$foo; # explained below
}
&foo for 1..3;
Typical output:
compile foo is 1 SCALAR(0xac18c0)
compile bar is 1 SCALAR(0xac1938)
runtime foo is 2 SCALAR(0xac18c0)
runtime bar is 2 SCALAR(0xac1938)
----------------
compile foo is 3 SCALAR(0xac18c0)
compile bar is 1 SCALAR(0xac1938)
runtime foo is 1 SCALAR(0xa63d18)
runtime bar is 2 SCALAR(0xac1938)
----------------
compile foo is 4 SCALAR(0xac18c0)
compile bar is 1 SCALAR(0xac1938)
runtime foo is 1 SCALAR(0xac1db8)
runtime bar is 2 SCALAR(0xac1938)
----------------
Note that the compile time $foo always refers to the same variable SCALAR(0xac18c0), and that this is also the run time $foo THE FIRST TIME the function is run.
The last line of &foo, push #baz,\$foo is included in this example so that $foo doesn't get garbage collected at the end of &foo. Otherwise, the 2nd and 3rd runtime $foo might point to the same address, even though they refer to different variables (the memory is reallocated each time the variable is declared).