Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Return value from code reference stored in dispatch table

by SteveTheTechie (Novice)
on Sep 01, 2013 at 03:01 UTC ( [id://1051762]=perlquestion: print w/replies, xml ) Need Help??

SteveTheTechie has asked for the wisdom of the Perl Monks concerning the following question:

(My first post here.) I am trying to get a return value from a function called via a reference stored in a dispatch table. This should be easy, but I keep having problems with it. For the sake of discussion, the following is not working for me...

$RtnVal = $ActionSubsM{$FormCmd}->( $FORM{'meetingid'} );

The above will compile, but will not run correctly. If I take off the "$RtnVal =" so that I am not storing the return value, I get valid execution, but no return value then.

I have tried storing the reference from the dispatch table in a temporary and working off that, but that did not work either.

Any ideas what could be going on?

Replies are listed 'Best First'.
Re: Return value from code reference stored in dispatch table
by davido (Cardinal) on Sep 01, 2013 at 03:25 UTC

    You haven't shown us enough to demonstrate the problem.

    use strict; use warnings; # $RtnVal = $ActionSubsM{$FormCmd}->( $FORM{'meetingid'} ); my %ActionSubsM; my $FormCmd = "some_action"; my %FORM; $FORM{meetingid} = "Hello world!\n"; $ActionSubsM{$FormCmd} = sub { return shift; }; my $RtnVal = $ActionSubsM{$FormCmd}->( $FORM{'meetingid'} ); print $RtnVal;

    ...outputs...

    Hello world!

    The code you are demonstrating is correct if the code you haven't demonstrated provides the necessary setup.

    The best thing you could do is boil your problem down to a 10 to 20 line example that can be executed, and that will exhibit the problem you're facing. There's a strong chance that in doing so, you'll find the problem yourself anyway. And if not, you will have something you can post for us to look at. ;)


    Dave

Re: Return value from code reference stored in dispatch table
by hdb (Monsignor) on Sep 01, 2013 at 06:45 UTC

    As davido pointed out, you have not provided enough information for us to be helpful. One thing to test though: as the correct execution seems to depend on the assignment of the return value, it could be a matter of context. By any chance, are you returning an array or hash?

      Ok, you want some context... (following are snippets... actual code is very long)

      use constant RTN_EXIT => 0; use constant RTN_CONTINUE => 1; use constant RTN_ERROR => 2; # ActionSubs hash ommitted for brevity.. (it contains over 40 entries +) %ActionSubsM = ( 'emailagenda' => \&emailagenda, 'defaultagenda' => \&defaultagenda, 'createnewdefaultagenda' => \&createnewdefaultagenda, 'deleteagenda' => \&deleteagenda ); # Parsing code ommitted for brevity... (loads %FORM hash) if (%FORM) { #Are there any entries in the %FORM hash from the par +ser? $FormCmd=$FORM{'action'} # Determine if the relevant commands are listed in any of the dispatch + hash tables, and if so, run the referenced subroutine with the appro +priate arguments.... $CmdFound=-1; + $RtnVal=RTN_EXIT; + #By default, all command +s exit if (exists $ActionSubs{ $FormCmd } ) { + #Found in %ActionSubs hash? $CmdFound = 1; #Run the subroutine from %ActionSubs corresponding to string argum +ent in $FORM{'action'}... $ActionSubs{ $FormCmd }->(); #HOW TO RETURN A VALUE HERE??? DOES + NOT WORK! unless ( $RtnVal == RTN_CONTINUE ) { exit; } } elsif ( ( exists $ActionSubsM{ $FormCmd } ) && $FORM{'meetingid'}) { + #Found in %ActionSubsM hash? $CmdFound = 1; #Run the subroutine from %ActionSubsE corresponding to string argu +ment in $FORM{'action'} with argument supplied by $FORM{'meetingid'}. +.. $ActionSubsM{ $FormCmd }->( $FORM{'meetingid'} ); #HOW TO RETURN A + VALUE HERE??? DOES NOT WORK! unless ( $RtnVal == RTN_CONTINUE ) { exit; } } # etc. 2 other hash dispatch tables looked at. }

      Sorry if you need more, but it is just too long to post the whole thing here. Hope this is enough.

      Basically, I cannot seem to get the following kind of thing to work:

      $RtnVal=$DispatchedSub($MyKey)->();

      The subroutine referenced by hypothetical "$DispatchedSub($MyKey)" is intended to return a constant telling the main routine whether it should exit or continue on and serve up the webpage. Trying to get the exits out of the subroutines.

      I tried the following, but it did not work either:

      $RtnVal=( $DispatchedSub($MyKey)->() );

      I do not have to do the explicit setting of $RtnVal (since it is set in the subs)... I just prefer explicit code for code clarity.

        I do not have to do the explicit setting of $RtnVal (since it is set in the subs)...     [emphasis added]

        This implies that  $RtnVal is a global. Along with hdb, I'm handicapped by not having an example of the referenced code, e.g., emailagenda(), but are you aware that a subroutine, named or otherwise, that does not have an explicit return statement implicitly returns the value of the last expression evaluated within the subroutine? A situation something like the one described in the OP can be imagined via this scenario:

        >perl -wMstrict -le "our $RtnVal; our $SomeOtherGlobal; ;; my $coderef = sub { $RtnVal = $_[0]; if ($RtnVal eq 'Ok') { $SomeOtherGlobal = 'Foo'; } }; ;; for my $arg (qw(Ok NotOk)) { $RtnVal = $coderef->($arg); print qq{RtnVal '$RtnVal'}; } ;; for my $arg (qw(Ok NotOk)) { $coderef->($arg); print qq{RtnVal '$RtnVal'}; } " RtnVal 'Foo' RtnVal '' RtnVal 'Ok' RtnVal 'NotOk'

        Admittedly, I am non the wiser now. Would it be possible to also show some of the code of the dispatch functions? Ideally, something like the following skeleton should help to isolate the problem: (depending on how much effort it is to strip it down like this)

        use strict; use warnings; sub emailagenda { # full definition here ... } %ActionSubsM = ( 'emailagenda' => \&emailagenda, ); my $RtnVal = $ActionSubsM{ 'emailagenda' }->( 'meetingid1' ); print "|$RtnVal|\n";
Re: Return value from code reference stored in dispatch table
by ig (Vicar) on Sep 05, 2013 at 03:45 UTC

    Can you clarify what you mean by "is not working for me" and "will not run correctly"?

    Basic debugging includes validating your assumptions. This can be tedious but often discloses the root cause of the problem, in my experience. I often find it easiest to log details to the terminal or a file, depending on the situation. Data::Dumper is very handy for logging data structures. In an undisclosed subroutine, almost anything could be going on so, as others have said, more information is necessary to provide more specific suggestions.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1051762]
Approved by McDarren
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-19 15:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found