Re: Just before subroutine returns
by Athanasius (Archbishop) on Aug 29, 2017 at 06:32 UTC
|
use strict;
use warnings;
use End;
foo(4);
foo(6);
sub foo
{
my ($n) = @_;
my $x = end { print "\$n = >$n<\n" };
return 1 if $n < 5;
$n *= 52;
return $n;
}
Output:
16:31 >perl 1810_SoPW.pl
$n = >4<
$n = >312<
16:31 >
Note that the assignment to $x is needed here, because of the way End works, even though the value of $x isn’t used.
Hope that helps,
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
karls-mac-mini:monks karl$ cpanm End
--> Working on End
Thanks and regards, Karl
«The Crux of the Biscuit is the Apostrophe»
perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Yes! That worked.. Thanks for your help!
| [reply] [Watch: Dir/Any] |
|
If you need to know which return returned, you might be able to wrap return using Keyword::Declare or Filter::Simple.
Be warned: These are very powerful, therefore dangerous to use.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
Re: Just before subroutine returns
by haukex (Archbishop) on Aug 29, 2017 at 08:46 UTC
|
| [reply] [Watch: Dir/Any] |
Re: Just before subroutine returns
by TheDamian (Vicar) on Aug 29, 2017 at 14:08 UTC
|
Another possibility would be the Scope::Upper module:
use Scope::Upper 'reap';
foo(4);
foo(6);
sub foo
{
my ($n) = @_;
reap { print "\$n = >$n<\n" }; # <-- Exec block when sub exits
return 1 if $n < 5;
$n *= 52;
return $n;
}
| [reply] [Watch: Dir/Any] [d/l] |
Re: Just before subroutine returns (depends)
by LanX (Saint) on Aug 29, 2017 at 15:49 UTC
|
You've got excellent answers, but I think it's important to explain that they fall into different categories.
The one category shown is basically installing a wrapper with the same name, and execute code before the original sub is entered and after it is exited. This is very stable and easy to achieve without changing the monitored sub, but comes with the drawback that information about internal state- i.e. lexical vars - is lost.
The other category shown is adding a lexical inside the sub, which holds an object. At the moment the sub (or generally the scope) is left , lexicals without reference count will be destructed and the DESTROY method will be called. This method can trigger a call back which can display the internal state in its closure.
But I'm not sure that you can know achieve info where - i.e. at which return - the sub is left.
A third - yet not demonstrated - category is to use the debugger. There you can define watch and trace expressions for subs which will trigger at different points. But this approach comes with dramatically reduced execution speed and won't be appropriate inside a long running process, like e.g. a web application.
So the appropriate answer depends on the exact nature of the information you (or someone else digging up this thread) wants to gather. :)
HTH
| [reply] [Watch: Dir/Any] |
|
The fourth category is those of us who are just glad we don't have to read the OP's code. This one sub has so many returns that he can't just put a log statement in front of each of them? Yikes!
| [reply] [Watch: Dir/Any] |
|
Log statement for each of many returns or log statement for each of many execution branches comes to the same number of log statements if you are trying to determine execution sequence as is implied by OP's question. So there is no "logging" advantage to multiple returns here, and there are vast opportunities to make the flow of code clearer by using early exits.
Multiply nested conditional code blocks and loops with a single exit: Yikes! (throws up hands and runs away).
Premature optimization is the root of all job security
| [reply] [Watch: Dir/Any] |
|
We - or at least me - don't answer for the OP but for the archive.
There are many possible cases where one needs to monitor subs, like e.g. needing to maintain foreign code and needing to figure out the intended mechanics.
And PM is not Stack-Overflow, our strength is to have deep discussions not just singular case recipes.
| [reply] [Watch: Dir/Any] |
|
Maybe the OP didn't write the code, just inherited it.
| [reply] [Watch: Dir/Any] |