Re: Closures and undefined subs
by ikegami (Patriarch) on Sep 26, 2007 at 14:15 UTC
|
use warnings;
sub outer {
my ($var) = @_;
sub inner {
print("$var\n");
}
inner();
}
outer("abc");
outer("def");
Variable "$var" will not stay shared at line 7.
abc
abc
Update: Solution:
use Math::RungeKutta;
sub outer {
my $var = ...;
my $dydt = sub {
... $var ...
};
...
($t, @y) = rkXXX(\@y, $dydt, $t, $dt);
...
}
You could local *dydt = sub { ... }; and \&dydt, but it's extra work for nothing here.
| [reply] [d/l] [select] |
|
|
I tried the my $blah = sub {}; deref later... with strict in a toy case and you were right it is alright.
If I do the same with my sub it fail with
Use of uninitialized value in subroutine entry at Levels/Level_IV.pm l
+ine 437.
Can't use string ("") as a subroutine ref while "strict refs" in use a
+t Levels/Level_IV.pm line 437.
If I wold use the local on dydt then it would crash with:
Undefined subroutine &Levels::Level_IV::_dydt called at /usr/lib/perl5
+/site_perl/5.8.8/Math/RungeKutta.pm line 74.
So I guess i might have some serious bug and misunderstanding somewhere in my code... Thats why I am here... | [reply] [d/l] [select] |
|
|
So I guess i might have some serious bug and misunderstanding somewhere in my code...
Yup, right there, *points to a line*.
Again, we can't debug code we can't see. Provide us with your work.
| [reply] |
|
|
|
|
Just to make it more clear:
Status quo:
use Math::RungeKutta;
sub outer {
my $var = sub_from_other_package();
no warnings qw(closure);
sub differ {
my $y = shift;
$var->[...]{...}{...}; etc.
...
return $res;
}
sub dydt {
my ($t,@y) = @_;
return differ($y);
};
($t, @y) = rkXXX(\@y, \&dydt, $t, $dt);
}
Neither local nor subs declared in lexicals help me out of my misery. The former is undefined the next is used as ""-ref. So There is a bug but what could it be that turns a sub into undefined?
Hope you still with me and not bored ;) | [reply] [d/l] |
|
|
|
|
|
Re: Closures and undefined subs
by Fletch (Bishop) on Sep 26, 2007 at 14:12 UTC
|
I think your problem is that you've misunderstood the scope of local. As soon as your out subroutine's scope is exited both of in and in2 are restored to their previous contents.
I'm not following exactly why you're trying to do this from your sample code, but I think what you'd want is to store the coderefs in lexically scoped scalars and call things using the arrow syntax rather than mucking about with local and what not.
sub out {
my $x = shift;
my $in = sub { ... };
my $in2 = sub { ...; my $rs = $in->( $arg ); ... };
return $x + $in_2->( );
}
| [reply] [d/l] [select] |
|
|
As soon as your out subroutine's scope is exited both of in and in2 are restored to their previous contents.
That's not a problem since he doesn't create any external references to in_2. He'd need lexicals in that case. For example, he'd need to use lexicals if the outer sub returned \&in_2.
Using lexicals doesn't help here. In addition to the more complex call syntax, using lexicals would create a memory leak if recursion was involved unless you explicitly undefed the lexical at the end of the outer sub.
| [reply] [d/l] [select] |
|
|
I am afraid use solved my problem but I am not happy for that :-)
RungeKutta needs \&in_2 in its own call.
I my opinion I need to write the closures as Rungekutta needs some equation in the differentiation sub. In this case the equation is too complex and needs variables that are imported into the outer sub of the package. So I guess I am in need of that much levels of complexity.
But what do you mean with lexicals? Could you give a "simple" example? Thank you.
| [reply] |
|
|
|
|
I disagree (which doesn't mean I'm right :-) - the code is parsed with the rest of the file; all refs to that code will be to the same piece. Lexicals FTW!
| [reply] |
|
|
Thank you for your replay but as I use the strict pragma and I wont disable it your solution will not work.
But nevertheless I guess you are right. Rungekutta uses the sub several times and local is not the right thing to use in this case.
What else could you suggest in order to make the inner subs using the vars from the outer one.
| [reply] |
|
|
You've done something wrong if you need to turn off strict. Fletch's code works fine with strict. And the inner subs have no problems using the variables in the outer one. Could you show us your code?
| [reply] |
Re: Closures and undefined subs
by KaiAllard_ (Initiate) on Sep 27, 2007 at 07:34 UTC
|
Thank you both for helping me that kindly.
Special thanks goes to ikegami.
It was a stupid error but sometimes one brain is just not enough :-) | [reply] |