http://qs321.pair.com?node_id=379760

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

I am posting info from page A to page B like so:

Page A:
#(within form)
print "<input type=text name =custtype value=kljlkjklj>";<BR><BR>
Page B:
$input = new CGI;<BR> $input->import_names('R');<BR> print "$R::custtype" ; ##prints out "kljlkjklj" successfully.

However I need to make this work using variable substitution, something like this:
$xx="custtype";
print "$R::$xx" ; ## but this prints only "custtype"???
Can anybody tell me what syntax I should use for this to work? Thanks.

Replies are listed 'Best First'.
Re: Variable Substitution within NameSpace
by matija (Priest) on Aug 03, 2004 at 17:59 UTC
    You shouldn't do what you're trying to do. Using variable substitution like that is slow, it's ugly, and it could be actively dangereous.

    What you should do instead is use the param method of CGI - like this:

    $input=new CGI; print param('custtype')." ".param($xx);
Re: Variable Substitution within NameSpace
by dsb (Chaplain) on Aug 03, 2004 at 18:04 UTC
    If I'm understanding you correctly, you want to pass form values. Fine. CGI.pm has methods suitable for doing that in a much neater way than what you are attempting. The param() function is the one you want.
    <input type="text" name="custtype" value="whatever'>
    So you've got that form element. Once you've submitted, call the param() function and bind that element to a variable in the script you call in the action attribute of your form definition.
    my $q = CGI->new(); my $cust = $q->param('custtype');
    param() examines the query string submitted to by your form and pulls the values out of that. In this case $cust would hold the value 'whatever'.


    dsb
    This @ISA my cool %SIG
Re: Variable Substitution within NameSpace
by davido (Cardinal) on Aug 04, 2004 at 04:28 UTC

    Creating a variable whos name is that of the value held in another variable or as literal text is called a symbolic reference. It's almost never the right way to do things, and unless you know intimately why not to use them, you're probably not presenting one of those few cases where they are the right way to do things.

    Let's say, for example, someone hits your CGI script with a page they've created themselves (instead of your page), and they submit a name of 'fh'. Now let's say your script already uses a variable named $fh... maybe it's going to be a filehandle you open later in the script. Oh oh, suddenly the script won't work because the name supplied by this malicious user's concaucted form submission conflicts with a variable name you're using in the script. Never let the outside world create variable names within your script. BAD BAD.


    Dave

Re: Variable Substitution within NameSpace
by broquaint (Abbot) on Aug 04, 2004 at 03:07 UTC
    This code should give you the desired behaviour

    Update: ah. I see CGI already has this method (even if it is implemented in a somewhat funky fashion).

    use Symbol qw/ qualify_to_ref gensym /; sub CGI::import_names { my($self, $pkg) = @_; $pkg .= '::' if substr($pkg, -2) ne '::'; my $tbl = qualify_to_ref $pkg; for($self->param) { my @vals = $self->param($_); my $glob = gensym; *$glob = @vals > 1 ? \@vals : @vals == 1 ? \$vals[0] : \undef; *$tbl->{$_} = $glob; } }
    HTH

    _________
    broquaint

Re: Variable Substitution within NameSpace
by sunadmn (Curate) on Aug 03, 2004 at 18:00 UTC
    I would say that you need to concatenate your scalars in the print statement as such:
    print "$R" . "::" . "$xx\n";
    I have tested this and it works fine.
    SUNADMN
    USE PERL
Re: Variable Substitution within NameSpace
by ccn (Vicar) on Aug 04, 2004 at 08:06 UTC
    $xx="custtype"; print "$R::$xx" ; ## but this prints only "custtype"???
    Can anybody tell me what syntax I should use for this to work?

    You can do exactly what you want, but it is not a good way for CGI applications.

    $xx="custtype"; print eval "\$R::$xx"; $erxx = eval "\$R::$xx"; print "R::xx = $errxx\n";
      i should have specified i'm working on Windows 2000.
      ccn's solution below worked:
      print eval "\$R::$xx";
      but the soln by SUNADM below only printed ::custtype. Maybe this would have worked on a Unix based OS.

      print "$R" . "::" . "$xx\n";

      I will though take the advice of avoiding using symbolic references in this manner and instead will use the CGI param method.
      Thanks for all the help. ytf