newbie: multi-screen CGI script

Discussion in 'Perl Misc' started by Don Stefani, Dec 28, 2003.

  1. Don Stefani

    Don Stefani Guest

    Don Stefani humbly exposes his stupidity to the world...

    Hello,

    Looking at the Perl Cookbook: (Recipe 19:12 Writing a Multiscreen CGI Script)

    I'm trying to do this:
    <code>
    %States = (
    'Default' => \&front_page,
    'Shirt' => \&shirt,
    'Sweater' => \&sweater,
    'Checkout' => \&checkout,
    'Card' => \&credit_card,
    'Order' => \&order,
    'Cancel' => \&front_page,
    );

    if ($States{$page}) {
    $States{$page}->(); # call the correct subroutine
    } else {
    no_such_page();
    }
    </code>

    But I can get the following to work. just fine, but 'The Cookbook' calls my method,
    "tedious and clumsy". I'm trying to work away from that! ;-)
    I'm testing with just two views, but I'll probably end with six or so.
    I must admit I only kind of know what I'm doing. I'm sure that's the key to the problem.
    I have a feeling I might be making things too complicated. A good hint and a flaming kick
    in the pants are very welcomed. TIA - Don

    <code>

    #!/usr/bin/perl -w
    use strict;
    use CGI;
    use Lib::AccountMgrGeneral;
    use Lib::MysqlModule;
    use Lib::WebForms;
    my $q = new CGI;
    my $amg = new AccountMgrGeneral;
    my $mysql = new MysqlModule;
    my $wf = new WebForms;

    my $view = $q->param('view') || 'srch';

    # HTML top-------------------------
    print "Content-type:text/html\n\n";
    print $amg->header();

    if ($view eq 'nsi')
    {
    print $wf->NameServerInput();
    }
    else
    {
    print $wf->SearchForm();
    }

    # HTML Bottom------------
    print $amg->footer();

    </code>
     
    Don Stefani, Dec 28, 2003
    #1
    1. Advertising

  2. Don Stefani

    Uri Guttman Guest

    >>>>> "DS" == Don Stefani <> writes:

    > I'm trying to do this:


    it is called a dispatch table.

    > <code>
    > %States = (
    > 'Default' => \&front_page,
    > 'Shirt' => \&shirt,
    > 'Sweater' => \&sweater,
    > 'Checkout' => \&checkout,
    > 'Card' => \&credit_card,
    > 'Order' => \&order,
    > 'Cancel' => \&front_page,
    > );


    > if ($States{$page}) {
    > $States{$page}->(); # call the correct subroutine
    > } else {
    > no_such_page();
    > }



    i prefer to save a hash lookup like this:

    if (my $page_sub = $States{$page}) {
    $page_sub->(); # call the correct subroutine
    }
    else {
    no_such_page();
    }

    and don't cuddle elses! (read perlstyle :).

    > But I can get the following to work. just fine, but 'The Cookbook'
    > calls my method, "tedious and clumsy". I'm trying to work away from
    > that! ;-)



    > #!/usr/bin/perl -w
    > use strict;
    > use CGI;


    good start

    > use Lib::AccountMgrGeneral;
    > use Lib::MysqlModule;
    > use Lib::WebForms;


    > my $q = new CGI;
    > my $amg = new AccountMgrGeneral;
    > my $mysql = new MysqlModule;
    > my $wf = new WebForms;


    my $obj = Class->new() ;

    direct object calls are safer. i think the issue is covered in perlobj.


    > my $view = $q->param('view') || 'srch';


    > # HTML top-------------------------
    > print "Content-type:text/html\n\n";
    > print $amg->header();


    > if ($view eq 'nsi')
    > {
    > print $wf->NameServerInput();
    > }
    > else
    > {
    > print $wf->SearchForm();
    > }


    you showed us the dispatch table and here is the working if/else
    code. but you haven't stated what happens with your broken code. also
    you haven't posted the entire broken script. if you just dropped the
    dispatch code into this, it should work but we can't see why it doesn't
    from this. note: make sure the dispatch hash is lexical (my) and is
    declared and assigned before it is used and outside any sub that uses
    it. it is static so doing it inside a sub would be slower (maybe not in
    the simple cgi case, but i have seen code where it was in a sub that is
    called repeatedly and that is not good).

    so put in your dispatch table (2 entries is fine) and tell us what
    happens when you run it. also the dispatch table didn't have the same
    vars as your code so they have to match. $page needs to become
    $view. the cookbook is not written to have its code used literally, you
    have to edit names and such to fit your needs.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Dec 28, 2003
    #2
    1. Advertising

  3. Don Stefani

    Don Stefani Guest

    Uri Guttman wrote:
    the cookbook is not written to have its code used literally, you
    > have to edit names and such to fit your needs.


    New, yes, but not that new! :)


    >my $obj = Class->new() ;


    >direct object calls are safer. i think the issue is covered in perlobj.

    Thanks, I'll be looking into that directly.

    OK, here's the code with the dispatch table followed by the errors.

    <code>
    #!/usr/bin/perl -w
    use strict;
    use CGI;
    use Lib::AccountMgrGeneral;
    use Lib::MysqlModule;
    use Lib::WebForms;
    my $q = new CGI;
    my $amg = new AccountMgrGeneral;
    my $mysql = new MysqlModule;
    my $wf = new WebForms;
    my $view = $q->param('view') || 'srch';

    # HTML top-------------------------
    print "Content-type:text/html\n\n";
    print $amg->header();

    ### the subroutines in the table are in WebForms.pm
    my %states = {
    'srch' => \&SearchForm,
    'nsi' => \&NameServerInput
    };

    if (my $page_sub = $states{$view})
    {
    $page_sub->(); # call the correct subroutine
    }
    else
    {
    print "no such page\n";
    }

    # HTML Bottom------------
    print $amg->footer();
    </code>

    <errors>
    command line:

    (NOTE: HTML output good until the good stuff is supposed to happen, then
    die.)

    >perl test2.cgi

    Reference found where even-sized list expected at test2.cgi line 18, <>
    line 1.
    no such page

    Browser:
    At default page ($views = 'srch')
    I get my "no such page" msg.

    when I send a param, $views = 'nsi', I get a 500 error.
    </errors>

    Thanks for your help, I just got a request for this small app and I'm in
    the first stages of switching from PHP to Perl. I'm trying to resist the
    urge to just do it in PHP. I'm hoping to learn from this project,
    although I feel a bit presumptuous. I hope I'm not "asking you to do my
    homework" if you know what I mean. My gut tells me the problem is that
    the way the table or the $page_sub test is written, it's looking for the
    subroutine in the main script. (?)

    Thanks,

    Don
     
    Don Stefani, Dec 28, 2003
    #3
  4. Don Stefani

    Uri Guttman Guest

    >>>>> "DS" == Don Stefani <> writes:

    > Uri Guttman wrote:
    > the cookbook is not written to have its code used literally, you
    >> have to edit names and such to fit your needs.


    > New, yes, but not that new! :)


    well, we have to make sure! :)

    > ### the subroutines in the table are in WebForms.pm
    > my %states = {
    > 'srch' => \&SearchForm,
    > 'nsi' => \&NameServerInput
    > };


    >> perl test2.cgi

    > Reference found where even-sized list expected at test2.cgi line 18,
    > <> line 1.


    look carefully at the code in the cookbook and your hash
    assignment. there is a distinct (but subtle difference). i will let you
    do this first before i (or someone else) gives you the answer. it is a
    good excercise to compare code with a microscope (char by char). and you
    will learn a valuable lesson about hashes and how to initialize them.

    > no such page


    > Browser:
    > At default page ($views = 'srch')
    > I get my "no such page" msg.


    > when I send a param, $views = 'nsi', I get a 500 error.
    > </errors>


    fix the first problem and maybe these will go away. many times early
    problems cause phony later ones that will magically go away when you fix
    the former.

    > Thanks for your help, I just got a request for this small app and I'm
    > in the first stages of switching from PHP to Perl. I'm trying to
    > resist the urge to just do it in PHP. I'm hoping to learn from this
    > project, although I feel a bit presumptuous. I hope I'm not "asking
    > you to do my homework" if you know what I mean. My gut tells me the
    > problem is that the way the table or the $page_sub test is written,
    > it's looking for the subroutine in the main script. (?)


    it is in your dispatch table for sure.

    and i gave you homework and didn't do yours! :)

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Dec 28, 2003
    #4
  5. Don Stefani

    Don Stefani Guest

    Uri Guttman wrote:
    >look carefully at the code in the cookbook

    () not {} duh! That actully crossed my mind (quickly I guess)

    But here's the new error on the command line: (dieing at the sub in
    question.
    <error>
    Undefined subroutine &main::SearchForm called at test2.cgi line 25, <>
    line 1.
    </error>

    I made a comment in the code, that the subs are in WebForms.pm,
    I need to get at them either in the table or the test?

    Thanks,
    Don

    <code>
    #!/usr/bin/perl -w
    use strict;
    use CGI;
    use Lib::AccountMgrGeneral;
    use Lib::MysqlModule;
    use Lib::WebForms;
    my $q = new CGI;
    my $amg = new AccountMgrGeneral;
    my $mysql = new MysqlModule;
    my $wf = new WebForms;
    my $view = $q->param('view') || 'srch';

    # HTML top-------------------------
    print "Content-type:text/html\n\n";
    print $amg->header();

    # the subroutines in the table are in WebForms.pm
    my %states = (
    'srch' => \&SearchForm,
    'nsi' => \&NameServerInput
    );

    if (my $page_sub = $states{$view})
    {
    $page_sub->(); # call the correct subroutine
    }
    else
    {
    print "no such page\n";
    }

    # HTML Bottom------------
    print $amg->footer();
     
    Don Stefani, Dec 28, 2003
    #5
  6. Don Stefani

    Uri Guttman Guest

    >>>>> "DS" == Don Stefani <> writes:

    > Uri Guttman wrote:
    >> look carefully at the code in the cookbook

    > () not {} duh! That actully crossed my mind (quickly I guess)


    good, you found it. did you learn the lesson? :)

    > But here's the new error on the command line: (dieing at the sub in
    > question.
    > <error>
    > Undefined subroutine &main::SearchForm called at test2.cgi line 25, <>
    > line 1.
    > </error>


    > I made a comment in the code, that the subs are in WebForms.pm,
    > I need to get at them either in the table or the test?


    you need to export them into main:: or fully qualify them in the
    dispatch table. i assume the module has its own package so those subs
    won't be seen by the code refs in the dispatch table as they are not in
    main::

    the simplest solution is to fully qualify them.

    > # the subroutines in the table are in WebForms.pm
    > my %states = (
    > 'srch' => \&SearchForm,
    > 'nsi' => \&NameServerInput
    > );


    'nsi' => \&WebForms::NameServerInput

    uri

    PS. have you gotten my emails? you sent me one and i haven't heard back
    since i replied.

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Dec 28, 2003
    #6
  7. Don Stefani

    Don Stefani Guest

    Uri Guttman wrote:
    > PS. have you gotten my emails? you sent me one and i haven't heard back
    > since i replied.


    Emails sent.

    That got rid of the command line error, but I get nothing as output in
    the browser. Not even my default subroutine. I'm ready to be "tedious
    and clumsy" for now in the name of progress! Break-time for bonzo.
    I'll get back at this later.

    Thanks,

    Don
     
    Don Stefani, Dec 28, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. praba kar

    Python-cgi or Perl-cgi script doubt

    praba kar, Jul 30, 2005, in forum: Python
    Replies:
    1
    Views:
    803
    Michael Sparks
    Jul 30, 2005
  2. Amir  Michail

    cgi relay for python cgi script

    Amir Michail, Oct 4, 2005, in forum: Python
    Replies:
    7
    Views:
    488
    Michael Ekstrand
    Oct 4, 2005
  3. Muzammil
    Replies:
    1
    Views:
    1,273
    red floyd
    Aug 28, 2008
  4. Gavri Savio Fernandez

    cgi = CGI.new causes the script to hang

    Gavri Savio Fernandez, Nov 30, 2003, in forum: Ruby
    Replies:
    2
    Views:
    278
    Ara.T.Howard
    Dec 1, 2003
  5. kath
    Replies:
    4
    Views:
    803
    J. Gleixner
    Apr 9, 2007
Loading...

Share This Page