use strict; # Constants used to define the type of question being asked use constant TYPE_MULTIPLE_CHOICE => 1; # multiple choice question use constant TYPE_FREE_TEXT => 2; # free response question # Some constants used internally use constant INDEX_MAGIC => 0; use constant INDEX_TYPE => 1; use constant INDEX_PROMPT => 2; use constant INDEX_CHOICES => 3; use constant INDEX_CORRECTVALUE => 4; use constant INDEX_POINTS => 5; # DEBUG: This magic number is stored in the first index of the question array. # Each function will check that the magic number is valid -- if not, then something # was gone wrong -- most likely this means you called the function wrong. use constant QUESTION_MAGIC_NUMBER => 23498234; use constant NO_CORRECT_ANSWER => -1; # This file define functions to read and write different elements of a particular question. # The whole element is stored in array as follows: # array[INDEX_MAGIC] holds a magic number used for debugging # array[INDEX_TYPE] holds the type of the question # array[INDEX_PROMPT] holds the prompt for the question, e.g. "When did Columbus discover America?" # array[INDEX_CHOICES] holds a reference to another array, with the possible answers to choose from, if any (empty array) # array[INDEX_CORRECTVALUE]] holds the index of the correct answer, or NO_CORRECT_ANSWER if none # array[INDEX_POINTS} holds the number of points for a question, if any # Internal debug function -- if this complains then you probably called the original function wrong sub questionCheckMagic { my ($question, $functionName, $caller_package, $caller_filename, $caller_line) = @_; if ($$question[INDEX_MAGIC] != QUESTION_MAGIC_NUMBER) { print "\n\n\n

ERROR! Bad question magic number in call to $functionName from $caller_filename, line $caller_line.\n " . "This probably means you called $functionName wrong.

\n\n\n"; exit(1); } } # Inputs: none # Returns: a new survey. Internally, this is just a reference to an empty array # sub questionCreateNew { my @anArray = (); $anArray[INDEX_MAGIC] = QUESTION_MAGIC_NUMBER; my $question = \@anArray; questionSetChoices($question, () ); # set to initially empty questionSetCorrectValue($question, NO_CORRECT_ANSWER()); return $question; } # Inputs: a question # Returns: the type of that question sub questionGetType { my($question) = @_; # get the input parameter questionCheckMagic($question, "questionGetType()", caller()); return $$question[INDEX_TYPE]; } # Inputs: (question, type) # where 'question' is the question to modify # and 'type' is the question type to be set # Returns: nothing (but modifies the question that was provided, # setting the type of that question)) sub questionSetType { my($question, $type) = @_; questionCheckMagic($question, "questionSetType()", caller()); $$question[INDEX_TYPE] = $type; } # Inputs: a question # Returns: the prompt of that question sub questionGetPrompt { my($question) = @_; # get the input parameter questionCheckMagic($question, "questionGetPrompt()", caller()); return $$question[INDEX_PROMPT]; } # Inputs: (question, prompt) # where 'question' is the question to modify # and 'prompt' is the question prompt to be set # Returns: nothing (but modifies the question that was provided, # setting the prompt of that question)) sub questionSetPrompt() { my($question, $prompt) = @_; questionCheckMagic($question, "questionSetPrompt()", caller()); $$question[INDEX_PROMPT] = $prompt; } # Inputs: a question # Returns: the choices of that question (an array of strings) sub questionGetChoices { my($question) = @_; # get the input parameter questionCheckMagic($question, "questionGetChoices()", caller()); my $array_ref = $$question[INDEX_CHOICES]; # get reference to the choices array return @$array_ref; # return copy of the array } # Inputs: (question, choices) # where 'question' is the question to modify # and 'choices' is the question choices to be set (an array of strings) # Returns: nothing (but modifies the question that was provided, # setting the choices of that question)) sub questionSetChoices() { my($question, @choices) = @_; questionCheckMagic($question, "questionSetChoices()", caller()); my @arrayCopy = @choices; $$question[INDEX_CHOICES] = \@arrayCopy;; } # Inputs: a question # Returns: the correctValue of that question sub questionGetCorrectValue { my($question) = @_; # get the input parameter questionCheckMagic($question, "questionGetCorrectChoice()", caller()); return $$question[INDEX_CORRECTVALUE]; } # Inputs: (question, correctValue) # where 'question' is the question to modify # and 'correctValue' is the question correctValue to be set # Returns: nothing (but modifies the question that was provided, # setting the correctValue of that question)) sub questionSetCorrectValue() { my($question, $correctValue) = @_; questionCheckMagic($question, "questionSetCorrectChoice()", caller()); $$question[INDEX_CORRECTVALUE] = $correctValue; } # Inputs: a question # Returns: the points of that question sub questionGetPoints { my($question) = @_; # get the input parameter questionCheckMagic($question, "questionGetPoints()", caller()); return $$question[INDEX_POINTS]; } # Inputs: (question, points) # where 'question' is the question to modify # and 'points' is the question points to be set # Returns: nothing (but modifies the question that was provided, # setting the points of that question)) sub questionSetPoints() { my($question, $points) = @_; questionCheckMagic($question, "questionSetPoints()", caller()); $$question[INDEX_POINTS] = $points; } 1;