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

Hi Monks!
I am trying to call a small perl script that has a menu I am using across a bunch of pages in my site. The issue I am having is that when I use this test program:
#!/usr/bin/perl -w use strict; use CGI qw(:standard); use URI::Escape; require "call_b.pl"; my $go_menu = &menu; #print "Content-type: text/html\n\n"; #print $go_menu;

It gets an error like:
Can't use an undefined value as a SCALAR reference
The error is from the call_b.pl script:
#!/usr/bin/perl -w use strict; use CGI qw(:standard); use URI::Escape; my $address; sub menu { print qq| <td> <ul> <li><a href="home.pl?contatc=${ uri_escape( $address ) }&amp;s +elected_tab=a" target="_top">home<b></b></a></li> <li><a href="home.pl?contatc=${ uri_escape( $address ) }&amp;s +elected_tab=b" target="_top"><span></span>about<b></b></a></li> <li><a href="home.pl?contatc=${ uri_escape( $address ) }&amp;s +elected_tab=c" target="_top"><span></span>contact<b></b></a></li> + </ul> </td> |; } 1;

Is this a glob error? What the best way to do this, if anyonw knows it would be nice!
Thanks for looking!

Replies are listed 'Best First'.
Re: SCALAR ref error help!
by delirium (Chaplain) on Aug 03, 2011 at 15:38 UTC

    There are a few bad things going on. First, change the name of the sub to something else; "menu" is used by one of the other modules, and there is a name collision.

    Second, $address doesn't get initialized anywhere. Third, don't print from the sub, return the value.

    Last, the uri_escape interpolation seems to be wrong somehow, but I didn't try to rewrite it as is, because it's hard to read, and you're doing it three times needlessly. Instead, call it outside of the qq statement. Try something like this:

    Main script:
    #!/usr/bin/perl -w use strict; use CGI qw(:standard); use URI::Escape; require "call_b.pl"; my $go_menu = &menu2; print "Content-type: text/html\n\n"; print $go_menu;
    call_b.pl
    #!/usr/bin/perl -w use strict; use CGI qw(:standard); use URI::Escape; my $address = uri_escape("some address"); sub menu2 { return qq| <td> <ul> <li><a href="home.pl?contatc=$address&amp;selected_tab=a" targ +et="_top">home<b></b></a></li> <li>etc..</li> </ul> </td> |; } 1;
Re: SCALAR ref error help!
by ikegami (Patriarch) on Aug 03, 2011 at 18:11 UTC
    "${foo}"
    means
    "$foo"
    but anything more complex and $... / ${ ... } becomes a derefence operator. Solutions:
    print qq|...contatc=|. uri_escape( $address ) .qq|...|;
    printf qq|...contatc=%s...|, uri_escape( $address );
    my $address_uri = uri_escape( $address ); print qq|...contatc=$address_uri...|;
    print qq|...contatc=${\( uri_escape( $address ) )}...|;
Re: SCALAR ref error help!
by Gulliver (Monk) on Aug 03, 2011 at 15:35 UTC

    The qq function does interpolation so ${ is seen as dereferencing something that isn't defined.

    You didn't mention the other warning "Subroutine menu redefined at call_b.pl line 9." I don't know anything about CGI or URI so not sure if that is an issue. But it looks like calling uri_escape is returning undef.

    Something else I noticed is that my $go_menu = &menu; will not assign anything to $go_menu since menu doesn't return anything.

      What if I change the menu sub to:
      sub menu { $address = q| <td> <ul> <li><a href="home.pl?contatc=${ uri_escape( $address ) }&amp;s +elected_tab=a" target="_top">home<b></b></a></li> <li><a href="home.pl?contatc=${ uri_escape( $address ) }&amp;s +elected_tab=b" target="_top"><span></span>about<b></b></a></li> <li><a href="home.pl?contatc=${ uri_escape( $address ) }&amp;s +elected_tab=c" target="_top"><span></span>contact<b></b></a></li> + </ul> </td> |; return; } Suggestions? Or would that be ok to have this line then: <code>my $go_ +menu = &menu;

      Thanks! </code>
Re: SCALAR ref error help!
by duyet (Friar) on Aug 04, 2011 at 06:44 UTC