S
sln
I still manage to run OS/2 on all boxes in the house...
WOOS2 - Windows on OS/2
-sln
I still manage to run OS/2 on all boxes in the house...
That's what I thought too.
Not actually that the shell was strange, but that it was strange
for a programmer of Ilya's cluefulness to be using Windows (which
was my erroneous guess as to why it was double quoted).
I asked him, and he explained else-thread.
I am fearless!
I am unmanageable! (and so is my hair)
Ben said:No. People seem to keep making this mistake. Named subs are *not*
closures in Perl 5, they simply keep a ref to all the variables they
reference.
Eric Pozharski said:Yes, that came in next feed. But I still puzled: I suppose most of
answering party, has run that one-liner. And I suppose they seemlesly
replaced double-quotes with single-quotes. That must be some kind of
Perl-specific mental disorder
However, since I'm insane,
Yor code example represents a closure wherein the value of a lexicalperl -wle "eval shift; delayed()" "my $x; $x=12; sub delayed {print $x}"
12
*After* `eval' is executed, the scope of $ARGV[0] is exited. But as
you see (and this is *very expected*), $x is not cleared on scope
exit.
variable declared outside of its scope gets captured. As usual, $x is
cleared at the end of the scope of $ARGV[0]
Why it is not completely correct:
perl -wle "eval shift; delayed()" "my $x; $x=12; sub delayed {print $x}"
12
*After* `eval' is executed, the scope of $ARGV[0] is exited. But as
you see (and this is *very expected*), $x is not cleared on scope
exit.
We appear to be in vehement agreement: anything that looks like
"initialization" in a "my" is not special, but is merely a standard
run-time assignment like any other. (My use of "initial value" may
have been inapt, especially in this example, where it's assigned in
the BEGIN block.)
Besides this unusual initialization/assignment thing, the docs specify
BEGIN is wrapped in an eval when it is run, which I thought odd.
WOOS2 - Windows on OS/2
Ilya said:Another sigh...  *If* the things were this simple...
perl -wle "my $x = 12, $x = 13; print $x"
Name "main::x" used only once: possible typo at -e line 1.
12
Wrong - already discussed.
variable declared outside of its scope gets captured. As usual, $x is
cleared at the end of the scope of $ARGV[0]
As my example shows, it's value is 12. So it is not "cleared".
Ben said:Not quite. Named subs are compiled once at compile time, and only keep a
ref to the outer lexicals as they existed then. This means that code
like
use warnings;
sub mkfoo {
my ($x) = @_;
sub foo { $x }
return \&foo;
}
say mkfoo($_)->() for 1..2;
gives
Variable "$x" will not stay shared at clos line 6.
1
1
whereas if you use an anon sub you get a fresh clone of the sub with
refs to the *current* set of outer lexicals, so code like
sub mkfoo {
my ($x) = @_;
return sub { $x };
}
say mkfoo($_)->() for 1..2;
gives
1
2
as expected. This is obviously important when using closures as
callbacks and such.
Quoth Ilya Zakharevich <[email protected]>:
Even weirder:
~% perl -le'$x = ($x = 5) + 1; print $x'
6
~% perl -le'my $x = (my $x = 5) + 1; print $x'
5
~%
![]()
Things are *nearly* that simple. While your points are valid in that
there's more to it, who in the world would write code like that?
for my $x (1..2) {
push @cvs, sub { $x };
}
and
for my $x (1..2) {
eval "sub foo { \$x }";
push @cvs = \&foo;
}
is that in the first case the anon sub is only compiled at compile time,
and both copies get the same optree, whereas in the second they are
(separately) compiled at runtime and each gets a different optree (that
happen to do the same thing). I would say that the first gives multiple
instances of a single closure, whereas the second gives multiple subrefs
that happen to do similar things to different variables. When I put it
like that it's hard not to say the distinction is purely academic.
The question of memory usage is important in some cases, but not really
relevant to the semantics.
For one thing, a CvCLONED CV uses some memory itself, so running out
of memory for cloned anon subs is just a matter of tweaking the
numbers a little higher...
Ilya said:To the contrary. If you ignore the memory usage and speed, there is
absolutely no point in having closures (for languages with eval()).
But you already noticed this...
Ilya Zakharevich wrote:
replace anonymous subroutine closures. For that matter, I think Perl
would be entitled to change eval in ways that break this. The eval docs
say that subroutine defined inside eval are visible after the eval, but
doesn't say what the behavior of outer scoped lexical variable would be
in that case.
My point was to explore the essence of what a closure is, not to propose
practical alternatives to anonymous subrefs.
Another sigh... *If* the things were this simple...
perl -wle "my $x = 12, $x = 13; print $x"
Name "main::x" used only once: possible typo at -e line 1.
12
So `my $x' has a runtime effect too: it puts the "new" $x on
stack - as different from plain `$x', which puts the "current" $x on
stack. And to muddy things yet more, the switch of the "current" $x
to the new value happens at time of `;' - which I consider a very
brain-damaged decision...
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.