Re: if(my) scope
by dada (Chaplain) on Apr 16, 2009 at 10:49 UTC
|
perltoot says:
Perl's notion of the right time to call a destructor is not well-defined currently, which is why your destructors should not rely on when they are called.
so the answer is: none of your business :-)
cheers,
Aldo
King of Laziness, Wizard of Impatience, Lord of Hubris
| [reply] |
|
Just to expand on the above:
In garbage-collected languages it is generally a bad idea to worry about exactly when a specific piece of data is garbage collected. It will happen at the runtime's convenience, no sooner, and no later. Doing immediate collection is generally more work (at runtime) than it is ever going to be worth.
So, expect that timing to change on different boxes, runs, and if you recompile. The only thing you are in good shape to be sure of it that it will happen after the variable has gone out of scope.
| [reply] |
|
Expanding a bit further.
That comment only applies to mark-and-sweep type garbage collection. As a general rule, Perl's reference-counted garbage collection is deterministic and mostly handles as you would expect. (Present case excepted, of course.)
Personally, I regret the loss of a defined, consistent object lifetime caused by using mark-and-sweep. Having the lifetime of a object determine the timing of events is quite useful. It's one of the reasons I prefer Perl and C++ to Java.
| [reply] |
|
Re: if(my) scope
by ikegami (Patriarch) on Apr 16, 2009 at 13:49 UTC
|
if is implemented in terms of and, and neither creates a scope at run-time (i.e. they don't call ENTER+LEAVE). That means they don't affect the life (refcount) of variables.
if only affects the visibility of the variable, a compile-time effect.
yuck!
Update: Just to be clear, I'm talking specifically about the condition expression, not the body of the if.
| [reply] [d/l] [select] |
|
Although I am sure you are right, how come:
use strict;
use warnings;
use Devel::Peek;
my $true = 1;
my $ref;
if ($true)
{
my $fred = 42;
$ref = \$fred;
}
print Dump($$ref);
Gives:SV = IV(0x3b2e0) at 0x3b2e4
REFCNT = 1
FLAGS = (PADMY,IOK,pIOK)
IV = 42
A reference count of 1, not 2? | [reply] [d/l] [select] |
|
You changed
if (my $var) { ... }
to
if (...) { my $var; ... }
use strict;
use warnings;
use Devel::Peek;
my $ref;
if ((my $fred = 42), 1)
{
$ref = \$fred;
Dump($$ref);
}
Dump($$ref);
SV = IV(0x816a5cc) at 0x814f684
REFCNT = 2
FLAGS = (PADBUSY,PADMY,IOK,pIOK)
IV = 42
SV = IV(0x816a5cc) at 0x814f684
REFCNT = 2
FLAGS = (PADBUSY,PADMY,IOK,pIOK)
IV = 42
A scope is created for if's curlies, but only a compile-time scope is created for the condition expression.
Btw, note the proper usage of Dump. | [reply] [d/l] [select] |
|
|
open my $fh, '<', $file or die;
so i'm asking myself if the possibility to setup a scope variable inside the argument of a function call is extended to _if_ statements too?
| [reply] [d/l] |
|
if (open(my $fh, '<', $qfn)) {
...read from $fh...
}
# $fh is out of reach here
Perl doesn't care where the my is to the point that it allows the following (even though the behaviour is officially undefined):
my $fh if ...;
| [reply] [d/l] [select] |
|
|
Re: if(my) scope
by targetsmart (Curate) on Apr 16, 2009 at 10:50 UTC
|
the phenomenon you noted is absolutly normal, if the reference count of $h goes to zero, it is automatically freed by perl, since it is associated with a object, the DESTROY method in the class will be called.
see perltoot Destructors
UPDATE
I generally talked about the way the DESTROY is called, but this is new to me, pardon if it caused some confusion.
Vivek
-- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
| [reply] |
|
package H;
sub DESTROY { print "DESTROY\n"; }
sub new { my $class = shift; bless {}, $class; }
{
print \$h, "\n";
if(my $h = H->new()) {
print \$h, "\n";
}
print \$h, "\n"; # <- This references the package var
# and would cause a strict error.
# Object is no longer accessible.
print "why now?\n";
} # <- The object is only destroyed here.
SCALAR(0x1829aac)
REF(0x1829abc)
SCALAR(0x1829aac)
why now?
DESTROY
| [reply] [d/l] [select] |
|
That wasn't the question. The question was why DESTROY is called after the outer { } ? after the if() block $h is no longer reachable, so why still holds a reference to the blessed instance?
| [reply] |
|
IMO the $h is visible entirely to the outer {} rather than 'if' block. I have to check the docs.
UPDATE
thanks to citromatik, but I know that the $h should get deallocated immediately after the 'if' block, but the example shown has confused me a bit, so I just coined my guess!. that is why i put 'In my opinion'. This is kind of learning about DESTROY and I will take it gleefully.
Vivek
-- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
| [reply] |
|
|
|
|
|
|