Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re: Avoiding user-input in sub calls.

by barrd (Abbot)
on Nov 01, 2003 at 13:14 UTC ( #303805=note: print w/replies, xml ) Need Help??

in reply to Avoiding user-input in sub calls.

Hi pekkhum,
There are indeed many ways of doing this, avoid using as that is too buggy.

What I normally do in this situation is create an HTML drop down like so (which takes away 'true' user input like a text form):

<select name="foo"> <option value="">Please make a selection <option value="first">First <option value="second">Second </select>
Then in the script have a hash pointing to functions:
my $doit = $q->param('foo'); my %functions = ('first' => \&one, 'second' => \&two );
This can then be called by dereferencing the sub:
&{ $functions{$doit} };
Obviously it would probably be wise to have a default to act as an error trap but hopefully the above might give you some ideas.

Another alternative would be to look at CGI::Application which is a handy tool for this kind of thing.

Replies are listed 'Best First'.
Re: Re: Avoiding user-input in sub calls.
by pekkhum (Sexton) on Nov 01, 2003 at 13:34 UTC
    This is the first mention I have heard of "dereferencing" a variable. I was looking for it in perldoc and found some references to it, but wish to double check what I have gathered. It seems to me:

    &{ $functions{$doit} };

    Would be seen by Perl as:

    "Take the value of $functions{$doit} and treat it as a sub name"

    Is that about right?
    I also keep seeing the use of my $thing = $q->param('whatever'); but am having trouble searching for it as I do not know what name it goes by...

    Thanks, for the help and better code.

      I also keep seeing the use of my $thing = $q->param('whatever'); but am having trouble searching for it as I do not know what name it goes by...

      This is the OO ('Object Oriented') interface to

      use CGI; my $q = CGI->new; my $value = $q->param('name');
      Roughly equivalent to:
      use CGI; my $value = CGI::param('name');
      except the OO way rends to be more flexible and earsier to modify (eg, you could write/use a module that inherits from CGI, by modifying only the
      statements. There's other reasons, but it's too early.

      --Bob Niederman,

      All code given here is UNTESTED unless otherwise stated.

      ..."dereferencing" a variable...
      It isn't dereferencing a 'variable' but a subroutine.
      "Take the value of $functions{$doit} and treat it as a sub name" Is that about right?
      More or less, yeah. But I have to admit that my powers of syntax explaining are pretty poor, I understand in my head what is going on but I don't want to lead you down the garden path with my crap explanations. There are many people here who could explain far more eloquently what is going on and hopefully one of them will step in to help both of us ;)

      &{ $functions{$doit} };

      Would be seen by Perl as:

      "Take the value of $functions{$doit} and treat it as a sub name"

      No, there's some confusion here about references. perlman:perlref is the definitive reference (no pun intended), but I'll try to give you the short answer.

      The syntax &{ SOMETHING } is, as you correctly said, a dereference. It says "Treat SOMETHING as a code reference", which means that the subroutine referred to by SOMETHING is executed. That means that SOMETHING is taken to be a reference, and in the example given, that's just what it is, as is evidenced by the code:

      my %functions = ('first' => \&one, 'second' => \&two );

      That \&one syntax is creating a hard reference to the subroutine one().

      If, however that SOMETHING is not actually a hard reference, but is just a plain old scalar, then the "value of the scalar is taken to be the name of a variable, rather than a direct link to a (possibly) anonymous value." (from perlman:perlfref). So if the code example would have looked like this:

      my %functions = ('first' => 'one', 'second' => 'two' );

      ... then you would be using a symbolic reference, which is what you mean by "Take the value of $functions{$doit} and treat it as a sub name". NOTE that this whole Symbolic reference business is disallowed by use strict 'refs', meaning that our friend SOMETHING must be an actual reference, and not just a name. This is probably a Good Thing.

      Hope this helps. And by the way, I think the syntax $coderef->() is preferable to the equivalent &{$coderef}, since I think it just looks clearer that you're calling a subroutine...


Re: Avoiding user-input in sub calls.
by skx (Parson) on Nov 02, 2003 at 15:14 UTC

     Using a HTML form with a drop down doesn't take away the user input; it's still not trusted.

     Any value may be entered by the user capable of saving your source somewhere and editing it; or facing the whole thing with LWP, etc.

     A minor point I know, but this came up at work fairly recently. All text fields were validated at submission time, but drop downs were for some bizarre reason taken as "trusted", and their values were injected directly into SQL. (Something else that's changed now).


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://303805]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (2)
As of 2018-05-26 06:56 GMT
Find Nodes?
    Voting Booth?