PDA

View Full Version : Undefined subroutine Error


ednit
12-15-2005, 06:35 PM
I have a script that gives me a undefined subroutine error:


#!/usr/bin/perl

require "main.pm";

use CGI::Carp qw(fatalsToBrowser);
use CGI;
$in = new CGI;
$userid = $in->param('userid');
$do = $in->param('do');
$catname = $in->param('catname');
$goto = $in->param('goto');
$description = $in->param('description');
$catid = $in->param('catid');
$ncname = $in->param('ncname');
$cdisp = $in->param('cdisp');
print "content-type: text/html\n\n";

if ($do eq "viewbylinks") {&udDB_vblinks;}
if ($do eq "viewbycategory") {&udDB_vbcategory;}

if ($do eq "") {&main;}
if ($do eq "ac") {&addcat;}
if ($do eq "AC2DB") {&AC2db;}
if ($do eq "ADDLINK") {&addlink;}
if ($do eq "ec") {&editcatform;}
if ($do eq "editcatc") {&editcatc;}
if ($do eq "delcat") {&delcatconfirm;}
if ($do eq "updatecname") {&updatecname;}
if ($do eq "nodcat") {&nodcat;}
if ($do eq "addlink") {&addalink;}
if ($do eq "yesdcat") {&dcatyes;}



##################
##### MAIN PAGE #####
##################

sub main {

$session_cookie = $in->cookie('webgo2_tracksession') ;
if (!$session_cookie) { &new_session; exit;}
else {
$userid = $session_cookie;
}

&opendb;
&users($userid);
if ($u_verified eq "no") {&closedb; &reverifyme; exit;}

$le = $dbh->prepare("select view from users_trackview where userid='$userid'");
$le->execute();
$ss = $le->fetchrow_hashref();
$thisusersview = $ss->('view');
if ($thisusersview eq "") {&closedb;
&header;
print qq~
Please choose how you want to view your tracking links:<br>
<a href="?do=viewbylinks">View By Links</a>&nbsp;(new system)&nbsp;&nbsp;&nbsp;<a href="?do=viewbycategory">View By Category</a>&nbsp; (old system)<br><br>
You may change your viewing preferences on your <a href="edit.cgi">Account Settings</a> page at any time. ~; &footer; exit; }



However, I do not get the error when I remove last part of it:

$le = $dbh->prepare("select view from users_trackview where userid='$userid'");
$le->execute();
$ss = $le->fetchrow_hashref();
$thisusersview = $ss->('view');
if ($thisusersview eq "") {&closedb;
&header;
print qq~
Please choose how you want to view your tracking links:<br>
<a href="?do=viewbylinks">View By Links</a>&nbsp;(new system)&nbsp;&nbsp;&nbsp;<a href="?do=viewbycategory">View By Category</a>&nbsp; (old system)<br><br>
You may change your viewing preferences on your <a href="edit.cgi">Account Settings</a> page at any time. ~; &footer; exit; }


The code is for a link tracking service where tracking links either viewed by category or by only the tracking links. In the code that seems to be messing it up the script is checking the preferences datbase, and if the user has not set their preferences the members are required to choose one option.

This is the error I get:
Undefined subroutine &main:: called at track.cgi line 54.

Line 54 is this one: $thisusersview = $ss->('view');

If anyone has any suggestions, I would appreciate it. I can also explain anything if needed.

Thanks.

FishMonger
12-15-2005, 08:56 PM
Try changing
$thisusersview = $ss->('view');

To
$thisusersview = $ss->{'view'};

ednit
12-15-2005, 10:17 PM
I kind of feel like a fool, should've cought that.

Thank you very much, that fixed it.

FishMonger
12-15-2005, 11:22 PM
Instead of all the if statements, you might want to look at using the switch module. http://search.cpan.org/~rgarcia/Switch-2.10/Switch.pm

Although, my personal preference would be to change the names of the subroutines to match the names of the 'do' param so you can reduce that block of if statements to a single statement.

$do eq "" ? &main : &$do;

ednit
12-16-2005, 01:17 AM
Thanks, I'll look into that - I learned to code by doing searches on Google, there are a lot of things that I've never heard of. . . actually, I've never heard of the anything that you'd mentioned in your post. I'm all for making my code shorter.

Thanks again.

FishMonger
12-16-2005, 02:01 AM
That line of code is using the trinary operator, which is a shorthand if/else statement.

It gets broken down into 3 sections. The first section is a true/false test. The second section ( between the ? and : ) is the code that gets executed if the test evaluates to true. The third section ( after the : ) is the code that gets executed if the test is false.

In this example, most of the "magic" is occuring if the test is false. &$do says to execute the subroutine name that was passed in and assigned to $do. So, if the 'do' form field passed 'addcat' as its value, then the &addcat subroutine would be executed. Likewise, if 'addlink' was passed, then the &addlink sub would be executed.

http://www.unix.org.ua/orelly/perl/prog3/ch03_16.htm