Using a variable to call a sub-routine...

Discussion in 'Perl Misc' started by Big Jay, Mar 15, 2006.

  1. Big Jay

    Big Jay Guest

    Hi all,

    I'm trying to call a sub-routine based on the value of a variable.

    More specifically, I'm developing a menu system, where each level of the
    menu has it's own sub-routine, but for a generalized "back" function, I'm
    trying to call the last menu based on a variable, something like:

    $lastMenu = apiMenu;

    &$lastMenu; #I want this to be the same as calling &apiMenu

    Does this make any sense?

    Any help is greatly appreciated!
     
    Big Jay, Mar 15, 2006
    #1
    1. Advertising

  2. "Big Jay" <> wrote in
    news:dP1Sf.1513$:

    > I'm trying to call a sub-routine based on the value of a variable.
    >
    > More specifically, I'm developing a menu system, where each level of
    > the menu has it's own sub-routine, but for a generalized "back"
    > function, I'm trying to call the last menu based on a variable,
    > something like:
    >
    > $lastMenu = apiMenu;
    >
    > &$lastMenu; #I want this to be the same as calling &apiMenu


    Use a hash table to map menu names to menu handlers.

    Sinan

    --
    A. Sinan Unur <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
     
    A. Sinan Unur, Mar 16, 2006
    #2
    1. Advertising

  3. Big Jay

    Big Jay Guest

    I think I'll try making a default menu functions sub-routine and pass it
    arguments for things like last menu... That should do the trick.

    "Big Jay" <> wrote in message
    news:dP1Sf.1513$...
    > Hi all,
    >
    > I'm trying to call a sub-routine based on the value of a variable.
    >
    > More specifically, I'm developing a menu system, where each level of the
    > menu has it's own sub-routine, but for a generalized "back" function, I'm
    > trying to call the last menu based on a variable, something like:
    >
    > $lastMenu = apiMenu;
    >
    > &$lastMenu; #I want this to be the same as calling &apiMenu
    >
    > Does this make any sense?
    >
    > Any help is greatly appreciated!
    >
     
    Big Jay, Mar 16, 2006
    #3
  4. Big Jay

    Matt Garrish Guest

    "Big Jay" <> wrote in message
    news:dP1Sf.1513$...
    > Hi all,
    >
    > I'm trying to call a sub-routine based on the value of a variable.
    >
    > More specifically, I'm developing a menu system, where each level of the
    > menu has it's own sub-routine, but for a generalized "back" function, I'm
    > trying to call the last menu based on a variable, something like:
    >
    > $lastMenu = apiMenu;
    >
    > &$lastMenu; #I want this to be the same as calling &apiMenu
    >
    > Does this make any sense?
    >


    They're called symrefs, and they're to be avoided. It's always better to use
    a hash:

    my %subs = ( apiMenu => \&apiMenu );
    my $lastMenu = 'apiMenu';
    $subs{$lastMenu}();

    Matt
     
    Matt Garrish, Mar 16, 2006
    #4
  5. Big Jay <> wrote:


    > I'm trying to call a sub-routine based on the value of a variable.



    That is what is known as a "dispatch table".

    You'll need to learn a bit about references to implement
    a dispatch table in Perl.

    (the word "subroutine" is not hyphenated.)


    > More specifically, I'm developing a menu system, where each level of the
    > menu has it's own sub-routine, but for a generalized "back" function, I'm
    > trying to call the last menu based on a variable, something like:
    >
    > $lastMenu = apiMenu;
    >
    > &$lastMenu; #I want this to be the same as calling &apiMenu



    -------------------
    #!/usr/bin/perl
    use warnings;
    use strict;

    my %menu_funcs = ( # a dispatch table
    Open => \&open_file,
    Edit => \&edit_file,
    Close => \&close_file,
    );

    foreach my $menu_choice ( 'Open', 'Edit', 'Close' ) {
    $menu_funcs{ $menu_choice }->(); # or: &{ $menu_funcs{ $menu_choice } }
    }

    sub open_file { warn "open_file() got called\n" }
    sub edit_file { warn "edit_file() got called\n" }
    sub close_file { warn "close_file() got called\n" }
    -------------------


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Mar 16, 2006
    #5
  6. Big Jay

    robic0 Guest

    On Wed, 15 Mar 2006 20:15:09 -0600, Tad McClellan <> wrote:

    >Big Jay <> wrote:
    >
    >
    >> I'm trying to call a sub-routine based on the value of a variable.

    >
    >
    >That is what is known as a "dispatch table".
    >

    Maybe Tad, you can explain "dispatch table" a phrase used
    exclusively for NT drivers...
    Expanding out of Perl Tad?

    >You'll need to learn a bit about references to implement
    >a dispatch table in Perl.
    >

    You might even have to learn NT driver developer package...
    >(the word "subroutine" is not hyphenated.)
    >
    >
    >> More specifically, I'm developing a menu system, where each level of the
    >> menu has it's own sub-routine, but for a generalized "back" function, I'm
    >> trying to call the last menu based on a variable, something like:

    Your developing a "menu system" in Perl? Hey Perl is *not* Windows!!!!!!!!!!!!!
    Take a Windows developer class from me. Do you know at least C ?
    >>
    >> $lastMenu = apiMenu;
    >>
    >> &$lastMenu; #I want this to be the same as calling &apiMenu

    >
    >
    >-------------------
    >#!/usr/bin/perl
    >use warnings;
    >use strict;
    >
    >my %menu_funcs = ( # a dispatch table
    > Open => \&open_file,
    > Edit => \&edit_file,
    > Close => \&close_file,
    >);
    >
    >foreach my $menu_choice ( 'Open', 'Edit', 'Close' ) {
    > $menu_funcs{ $menu_choice }->(); # or: &{ $menu_funcs{ $menu_choice } }
    >}
    >
    >sub open_file { warn "open_file() got called\n" }
    >sub edit_file { warn "edit_file() got called\n" }
    >sub close_file { warn "close_file() got called\n" }
    >-------------------


    Sorry man, its all bullshit.
     
    robic0, Mar 16, 2006
    #6
  7. Big Jay

    robic0 Guest

    On Wed, 15 Mar 2006 20:35:25 -0500, "Matt Garrish" <> wrote:

    >
    >"Big Jay" <> wrote in message
    >news:dP1Sf.1513$...
    >> Hi all,
    >>
    >> I'm trying to call a sub-routine based on the value of a variable.
    >>
    >> More specifically, I'm developing a menu system, where each level of the
    >> menu has it's own sub-routine, but for a generalized "back" function, I'm
    >> trying to call the last menu based on a variable, something like:
    >>
    >> $lastMenu = apiMenu;
    >>
    >> &$lastMenu; #I want this to be the same as calling &apiMenu
    >>
    >> Does this make any sense?
    >>

    >
    >They're called symrefs, and they're to be avoided. It's always better to use
    >a hash:
    >

    Symrefs? Stand for Symbolic References?

    Can you please explain, for the beginners, when you use such wild assed terms..
    The FLAWWED_FAQ tries I know rescue beginners when it sees such phrases
    (that seem to make sence).

    However, gone are the days of intellecutal arragoance! If you think your
    audience doesen't understand your logic or analogy, its up to *YOU* to
    provide the full documentation in your words.

    Buddy, who the **** knows what your talking about? Don't invoke
    Einstein's theory of realtivity with out explaining yourself!!

    I'm gonna hold everyone to this, period !!

    -<snip>-
     
    robic0, Mar 16, 2006
    #7
  8. Big Jay

    Uri Guttman Guest

    >>>>> "r" == robic0 <robic0> writes:

    r> On Wed, 15 Mar 2006 20:15:09 -0600, Tad McClellan <> wrote:
    >> That is what is known as a "dispatch table".
    >>

    r> Maybe Tad, you can explain "dispatch table" a phrase used
    r> exclusively for NT drivers...
    r> Expanding out of Perl Tad?

    hmm, did your addlepated brain ever allow the possibility that the term
    dispatch table is slightly older than nt? and the concept is even older
    than that? you really think that redmond both invented the concept and
    the term? i was coding dispatch tables way before uncle bill robbed his
    first billion. but you won't understand this anymore than you know why
    the sky is blue.

    how do you function in the real world with such delusions and
    miscomprehensions? but your alter ego rm will soon pop in. ever notice
    how the two of you are never seen at the same time?

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 16, 2006
    #8
  9. Big Jay

    /usr/ceo Guest

    robic0 wrote:
    > On Wed, 15 Mar 2006 20:15:09 -0600, Tad McClellan <> wrote:
    >
    > >Big Jay <> wrote:
    > >
    > >
    > >> I'm trying to call a sub-routine based on the value of a variable.

    > >
    > >
    > >That is what is known as a "dispatch table".
    > >

    > Maybe Tad, you can explain "dispatch table" a phrase used
    > exclusively for NT drivers...
    > Expanding out of Perl Tad?


    Uh, robic0...?? Don't make one of us have to track you down by IP,
    come to your cubical at the library, and pull out all your octets one
    by one with needle-nosed pliers, ok? Your trolling isn't welcome here.
    Maybe try one of the alt groups or something, hmmmm???

    /usr/ceo
     
    /usr/ceo, Mar 16, 2006
    #9
  10. Tad McClellan <> wrote:

    > Big Jay <> wrote:
    >
    >
    >> I'm trying to call a sub-routine based on the value of a
    >> variable.

    >
    >
    > That is what is known as a "dispatch table".
    >
    > You'll need to learn a bit about references to implement
    > a dispatch table in Perl.
    >
    > (the word "subroutine" is not hyphenated.)


    I wrote a tentative entry for the FAQ about this a year or two ago,
    but never quite got around to submitting it, mainly because I
    thought it should be vetted by some with more knowledge and
    experience than myself.

    Anyway, here it is:



    How do I call a subroutine when I have the name of the subroutine?
    How do I use a dispatch table?

    A dispatch table is just a special name for a hash with code
    references. (see L<perlref>) The code references can be from any
    source, for example, references to named subroutines in or imported
    into a module, references to fully qualified subroutine names, or
    anonymous code references.

    Here is an example of a dispatch table:

    my %dispatch = (
    update => \&update,
    add => \&add,
    other => \&Foo::bar,
    error => sub { die "Error: @_" }
    default => \&do_something,
    );

    Put the creation of the dispatch table outside of any subroutine
    that uses it so it (the dispatch table) is created at compile time
    and not recreated in each call to the subroutine that does the
    dispatching.

    If we have a desired name in the scalar $input, the associated
    subroutine can be called using $dispatch{$input}->().

    The code should always handle the case where the input value is not
    a key of %dispatch, so we might implement the call like this:

    ($dispatch{$input} || $dispatch{'default'})->(@arguments);
     
    David K. Wall, Mar 16, 2006
    #10
  11. Big Jay

    Uri Guttman Guest

    >>>>> "DKW" == David K Wall <> writes:

    DKW> How do I call a subroutine when I have the name of the subroutine?
    DKW> How do I use a dispatch table?

    DKW> A dispatch table is just a special name for a hash with code
    DKW> references. (see L<perlref>) The code references can be from any
    DKW> source, for example, references to named subroutines in or imported
    DKW> into a module, references to fully qualified subroutine names, or
    DKW> anonymous code references.

    A dispatch table is just a special name for a hash which holds pairs of
    name/code references for its keys/values. The code references can refer
    to named subs, anonymous subs, package local subs or fully qualified
    subs.


    DKW> Here is an example of a dispatch table:

    DKW> my %dispatch = (
    DKW> update => \&update,
    DKW> add => \&add,
    DKW> other => \&Foo::bar,
    DKW> error => sub { die "Error: @_" }
    DKW> default => \&do_something,
    DKW> );

    DKW> Put the creation of the dispatch table outside of any subroutine
    DKW> that uses it so it (the dispatch table) is created at compile time
    DKW> and not recreated in each call to the subroutine that does the
    DKW> dispatching.

    and make sure it is initialized before it gets used. a classic and
    subtle bug is declaring the table near the sub that does the
    dispatching. if this sub gets called before the table assignment is
    done, it will dispatch on an empty table. if this code is in a module,
    it will probably not fail that way since the base code of the module
    will be executed including the table assignment. but if this is all in
    the main script, the call could be made at the top whereas the
    assignment is lower down. then you should wrap the assignment AND its
    dispatching sub into a single BEGIN block:

    BEGIN {

    my %dispatch = ( blah ...
    ) ;

    sub handle_dispatch {

    blah
    }
    }

    DKW> If we have a desired name in the scalar $input, the associated
    DKW> subroutine can be called using $dispatch{$input}->().

    DKW> The code should always handle the case where the input value is not
    DKW> a key of %dispatch, so we might implement the call like this:

    DKW> ($dispatch{$input} || $dispatch{'default'})->(@arguments);

    the default shouldn't be an entry in the dispatch table unless it is
    allowed to be called by that name.

    another point is that you can have multiple names calling the same
    code. this effectively allows aliases for the code. one variation is
    that the name is also passed as an argument to the code to handle
    similar cases in one sub. also in some designs you don't allow a default
    and if the name is not valid you issue some error.

    dispatch tables are a great tool but you need to make sure this FAQ
    covers enough points to make it useful. and when you finish this, just
    send it into the FAQ autopost thing and the cabal will take a look at
    it. i would support adding it to the FAQ.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Mar 16, 2006
    #11
  12. Uri Guttman wrote:
    > >>>>> "r" == robic0 <robic0> writes:

    >
    > r> [ Laughable nonsense ]
    >
    > [ criticism ]


    Uri, please do not feed the troll.
     
    Brian McCauley, Mar 17, 2006
    #12
  13. /usr/ceo wrote:

    > Your trolling isn't welcome here.


    Do you really imagine that is is probable that the troll doesn't know
    this?

    You are feeding the troll.

    Please consider applying the following guidelines:

    * Never directly follow-up a troll's posts.

    * Never directly address any statement to a troll.

    * As much as possible avoid mentioning a troll by name.
     
    Brian McCauley, Mar 17, 2006
    #13
  14. Big Jay

    robic0 Guest

    On Wed, 15 Mar 2006 23:54:49 GMT, "Big Jay" <> wrote:

    >Hi all,
    >
    >I'm trying to call a sub-routine based on the value of a variable.
    >
    >More specifically, I'm developing a menu system, where each level of the
    >menu has it's own sub-routine, but for a generalized "back" function, I'm
    >trying to call the last menu based on a variable, something like:
    >
    >$lastMenu = apiMenu;
    >
    >&$lastMenu; #I want this to be the same as calling &apiMenu
    >
    >Does this make any sense?
    >
    >Any help is greatly appreciated!
    >


    I guess I'll try to appretiate your post one more time, being in a
    diffrent frame of mind.

    Like I said, don't really know *what* type of menu system your talking about,
    the availability of options on each level, saved frames, and so forth..

    It does not appear you want anything other than a level scalar array of hashes
    that contain sub references to handlers that know and where it is and can react,
    based on some interpreted *key* selected via keyboard (?) input.

    The sub's probably have identical parameters, or passed a constant structure
    from which more sub/level, individual data can be processed. This is not easy.

    Also, you may want to save state of the data previously entered if its revisited.
    Likewise, you may want to carry around a master data structure that has been sucessfully
    populated from previous visits as you progress down the menu tree towards the
    final *SUBMIT/SAVE* conclusion. Again not easy. But entirely possible.

    Consider that its a windows menu tree, where you are calling successive dialog's,
    populating a master data structure along the way. A cancel out of a single dialog
    invalidates *only* a portion of the master that you are populating. Consecutive
    <backspace> could load previously entered data (incase the user just wanted to
    change one item), but would probably invalidate the forward data if a backward
    change deems it so.

    .............

    One way is:

    # in key form, @menutext_hasharrays contains "Text" to display and
    # corresponding index to the selected @m(x) that is current.

    @menutext_hasharrays = (
    # main
    {'N' => [1, "'N'ext"], 'Q' => [3, "'Q'uit"],
    'A' => [4, "'A'item"], 'B' => [5, "'B'item"], 'C' => [6, "'C'item"] },
    # level 1
    {'N' => [1, "'N'ext"], 'B' => [2, "'B'ack"], 'Q' => [3, "'Q'uit"],
    'A' => [4, "'A'item"], 'B' => [5, "'B'item"], 'C' => [6, "'C'item"] },
    # level 2
    {'N' => [1, "'N'ext"], 'B' => [2, "'B'ack"], 'Q' => [3, "'Q'uit"],
    'A' => [4, "'A'item"], 'B' => [5, "'B'item"] },
    # level 3
    {'N' => [1, "'N'ext"], 'B' => [2, "'B'ack"], 'Q' => [3, "'Q'uit"],
    'A' => [4, "'A'item"], 'B' => [5, "'B'item"], 'C' => [6, "'C'item"] },
    );

    # @m(x) handler array's:
    # index 0 always equals index to @menutext_hasharrays (for menu display options and
    # holds indexes to handlers at the current level, this so a particular item need not
    # be in order when displaying the option),
    # index 1 always equals ref to "next" @m(x) array
    # index 2 always equals ref to "last" @m(x) array (if back)
    # index 3 always equals ref to "quit", can be custom specific to a menu ..
    # index 4 - ... are the specific handlers for this menu level
    # indexes > 2 are handlers

    @mm = (0, \@m1, undef, \&quit);
    @m1 = (1, \@m2, \@mm, \$quit, \&h11, \&h12, \&h13);
    @m2 = (2, \@m3, \@m1, \$quit, \&h21, \&h22);
    @m3 = (3, undef, \@m2, \$quit, \&h31, \&h32, \&h33);

    ..........

    The rest is left as an exercise.

    You have to read between the lines. All values in the anom array's in
    @menutext_hasharrays are arbitrary except for the indexes into the @m(x) handler array's
    The concept is driven from the knowledge of initially starting with a known @m(x) array
    by default.

    This is one of several ways to implement this in Perl, depending on your perspective.
    There is always a *static* degree to this process. It *always* has some degree of
    indirection, ie: building tables of references to others.

    This is for character driven menu's. There's another way which is a derritive of this
    that involves further indirection might drive you insane to even think about it.
    Or that I don't care to explain...

    The graphic method and the issues discussed above all can work depending on what wants
    to be accomplished.

    Hey, I'm not getting paid for this shit....

    robic0
     
    robic0, Mar 19, 2006
    #14
  15. Big Jay

    robic0 Guest

    On 17 Mar 2006 08:13:42 -0800, "Brian McCauley" <> wrote:

    >
    >/usr/ceo wrote:
    >
    >> Your trolling isn't welcome here.

    >
    >Do you really imagine that is is probable that the troll doesn't know
    >this?
    >
    >You are feeding the troll.
    >
    >Please consider applying the following guidelines:
    >
    > * Never directly follow-up a troll's posts.
    >
    > * Never directly address any statement to a troll.
    >
    > * As much as possible avoid mentioning a troll by name.


    K, Brian McCauley is the troll..... sorry I could not resist!
     
    robic0, Mar 19, 2006
    #15
  16. Big Jay

    robic0 Guest

    On 15 Mar 2006 21:02:32 -0800, "/usr/ceo" <> wrote:

    >robic0 wrote:
    >> On Wed, 15 Mar 2006 20:15:09 -0600, Tad McClellan <> wrote:
    >>
    >> >Big Jay <> wrote:
    >> >
    >> >
    >> >> I'm trying to call a sub-routine based on the value of a variable.
    >> >
    >> >
    >> >That is what is known as a "dispatch table".
    >> >

    >> Maybe Tad, you can explain "dispatch table" a phrase used
    >> exclusively for NT drivers...
    >> Expanding out of Perl Tad?

    >
    >Uh, robic0...?? Don't make one of us have to track you down by IP,
    >come to your cubical at the library, and pull out all your octets one
    >by one with needle-nosed pliers, ok? Your trolling isn't welcome here.
    > Maybe try one of the alt groups or something, hmmmm???
    >
    >/usr/ceo


    This coming from a user who decides to take a directory name.
    God help all the knowledge to date *NOT* reset on this faggat ...
     
    robic0, Mar 19, 2006
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. D. Shane Fowlkes

    just tinkering with a Sub Routine in ASP.NET

    D. Shane Fowlkes, Nov 12, 2003, in forum: ASP .Net
    Replies:
    5
    Views:
    442
    Scott M.
    Nov 13, 2003
  2. Neo
    Replies:
    6
    Views:
    418
    Mark A. Odell
    Dec 2, 2003
  3. Neo
    Replies:
    2
    Views:
    345
    Arthur J. O'Dwyer
    Dec 9, 2003
  4. Ben
    Replies:
    2
    Views:
    922
  5. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    2,083
    Lawrence D'Oliveiro
    May 20, 2011
Loading...

Share This Page