Question and answer system for the web

YAML as a Model

Catalyst normally relies on database-backed data models; however, in this case the data is stored in a YAML file. It isn't too difficult to define your own model. The line

script/quizshow_create.pl model Questions

creates the lib/QuizShow/Model/Questions.pm file, which you need to populate with the code shown in Listing 2, Mod-Questions.pm.

Listing 2

Mod-Questions.pm

01 ###########################################
02 package QuizShow::Model::Questions;
03 # Mike Schilli, 2008 (m@perlmeister.com)
04 ###########################################
05 use strict;
06 use warnings;
07 use base 'Catalyst::Model';
08 use YAML qw(LoadFile);
09
10 my $FILE = "/home/mschilli/data/quiz.yml";
11
12 ###########################################
13 sub total {
14 ###########################################
15     my $yml = LoadFile $FILE;
16     return scalar @$yml;
17 }
18
19 ###########################################
20 sub get_question {
21 ###########################################
22     my($m, $index) = @_;
23
24     my $yml = LoadFile $FILE;
25     return undef if $index > $#$yml;
26     return @{ $yml->[$index] };
27 }
28
29 1;

The YAML file in Figure 3 defines an array of entries for each question posed by the test. Comment lines starting with # are ignored. The individual array entries start with a hyphen, and comprise sub-arrays with four elements each: the wording of the question, followed by the right answer, and two incorrect answers.

The $FILE variable in Listing 2 defines the path to the YAML file. The total() method parses the data and returns the total number of questions to allow the web application to display the number of questions remaining. total() provides the YAML array in a scalar context to this end; this returns the array length in Perl.

The get_question() method in line 20 retrieves the questions and answers for an array index (0 to n-1) and returns them as a list. If the index does not point to a valid entry, it returns undef. This is the signal to the online quiz that it has run out of questions and has to display the final score.

If the controller wants to access the encapsulated data model, it grabs the Catalyst object and calls $c->model('Questions'). This gives it an instance of the Questions data model whose get_question() and total() methods it can then use.

Installation

To install the ready-to-run Catalyst application on the production server, simply enter the typical three commands for CPAN modules in the project directory:

cd QuizShow
perl Makefile.PL
make install

Catalyst then injects the modules, templates, and scripts required by the application into the Perl hierarchy defined on the used platform.

Instead of the Perl server included by the distribution, I would recommend using a Mod_perl installation to allow Apache 2 to execute the program more quickly:

PerlModule QuizShow
<Location />
  SetHandler modperl
  PerlResponseHandler QuizShow
</Location>

An Apache 1.3 configuration also is described by the exhaustive Catalyst documentation. If speed is not an issue, there is also a CGI script that Catalyst installs as quizshow_cgi.pl. If you drop the script into the web ser-ver's CGI directory and enter the URL http://localhost/cgi/quizshow_cgi.pl/quiz, the quiz launches.

If you migrate from the test server to the web server, note that the sessions reside below the /tmp/quizshow directory and the web server will normally run under a different user account. If you modify the user privileges correspondingly, the new server can just go on using the old session store.

Apache 2 and Mod_perl 2 cause a similar problem. The Perl module is easily installed on Ubuntu using the libapache2-mod-perl2 and libcatalyst-engine-apache-perl packages, however, Session::Store:: FastMmap complains that it can't handle threads. The alternative Session::Store::File works perfectly; just modify lib/QuizShow.pm accordingly.

Unfortunately, Apache 2 uses the root account to create the directories and is unable to access them later when it spawns non-privileged child processes. sudo chown -R www-data /tmp/quizshow solves the problem by assigning the ownership of the session store to the web server user (can also be nobody).

Further Reading

Catalyst has much more to offer than just the functions I discussed. It is equally suited to small or large projects, in which team members split up the work to focus on different areas of the project. It offers a mature test framework that is automatically generated when you create a new project. Dynamic Ajax web pages are also supported. With this approach, the web application uses an extension module to send, for example, Json data to browser-side Javascript – and a cozy Web 2.0 feeling ensues because page reloads are no longer necessary to refresh the display.

Besides the online manual and tutorials [4], the book Catalyst [6] offers a very useful overview, although it is not a perfect reference manual as it lacks both an index and the in-depth detail a reference book requires.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus

Direct Download

Read full article as PDF:

076-080_perl.pdf  (611.30 kB)

News