While shmem has demostrated the calling styles, I'd like to add some notes. Nevertheless, you'll find more on perlreftut or perlref.

So basically, as f00li5h said, you're building a dispatch table. You use a key/index based on user input to obtain the correspondent code (subroutine) and dispatch it.

The first style,

$op_map{$op_choice}->(@args);
As you probably know, the selected subroutine is in $op_map{$op_choise}, a code reference. A common way to dereference a reference is by using the arrow operator. The parentheses are there for passing in parameters and required in this case, whether or not you actually have parameters to pass in. That's the basic way to call functions (allthough you can omit the parentheses in some cases). So if you had no parameters, you would call it $op_map{$op_choice}->();

The second style,

&{$op_map{$op_choice}}(@args);
Another approach in dereferencing is by surrounding the references in {} and prepending it with a sigli (a character that signifies a thing), hence the &{}. As you may recall, the & is (optionally) used to call a subroutine. The parentheses are there, again, for passing in parameters and required if you do have parameters to pass in. Otherwise, &{$op_map{$op_choice}}; will do (but see WARNING below).

As for myself, I'd rather like to firstly check the input if it indeed exists in the table. This way, if the input is not one of the keys, I have options whether to simply throw an exception or use some default instead.

die "Unknown choice: $op_choice\n" unless my $cmd = $op_map{$op_choice};
Or, if I set a default choice,
my $default = 'OP1'; my $cmd = $op_map{$op_choice} || $op_map{$default};
And later,
$cmd->();
Or,
&$cmd; # see WARNING below
I see the first style is more elegant, and the first is shorter. I personally prefer the second one.

WARNING: One has to be careful of the &$cmd. This form has special meaning in that it passes in the parameters for the current subroutines (@_) to the subroutine reference in $cmd. So, &$cmd is basically the same as &$cmd(@_). If this is what you want then go ahead. If you're in doubt however, use parentheses, whether or not you have parameters. In fact, this is the recommended practice, whether or not it's explicitly called inside a subroutine. Oh well, you may never know when your whole script is actually wrapped in a generated subroutine (thinking mod_perl for example).


Updated: added the WARNING. Thanks ikegami :-)

Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!


In reply to Re: calling a function as a value from a hash by naikonta
in thread calling a function as a value from a hash by shobhit

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.