Массив Perl, измененный неизвестным источником - PullRequest
0 голосов
/ 25 октября 2018

Я полагаю, что столкнулся с ошибкой, но хотел быть уверен, что я что-то не упустил.Мой стажер работает над веб-сайтом, на котором будут проходить тесты с переменным количеством вопросов с переменным количеством ответов, которые должны пройти сотрудники для обучения.Мы храним вопросы в двумерном массиве, содержащем идентификатор вопроса и текст вопроса.Мы перебираем этот массив для создания элементов div для каждого вопроса, скрывая все, кроме первого, и используем этот идентификатор вопроса, чтобы получить ответы на этот вопрос в цикле.

Однако мы сталкиваемся с тем, что когдаЦикл for достигает последнего индекса, пустой элемент помещается в @questions.Это увеличивает результат scalar @questions на единицу, и этот цикл повторяется бесконечно.Однако мы не можем выяснить, является ли причиной того, что пустой элемент помещается в @questions?

my @questions;

my $getQuestion = $dbh->prepare("
    SELECT ID, Question 
    FROM ACTestQuestions
    WHERE TestID = ?
");

$getQuestion->execute(1);

while(my @question = $getQuestion->fetchrow_array()){
    push(@questions, \@question);
}

my $sth = $dbh->prepare("
    SELECT ID, AnswerText, CorrectAnswer
    FROM ACTestAnswers
    WHERE QuestionID = ?
    ORDER BY SortOrder
");

# Irrelevant parts skipped

for(my $i = 0; $i < scalar @questions; $i++){
    my $qCount = 1;
    my $qID = $questions[$i][0];
    my $hideClass = "hide";

    if($i == 0){
        $hideClass = "";
    }
    print <<"END_HTML";
    <div id="question-$questions[$i][0]"  class="centered question-container $hideClass">
        <h1 class="text-center">Question &num;$qCount</h1>
        <h4 class="text-center" >$questions[$i][1]</h4></br>
            <form method="get">
                <table>                     
END_HTML

    if($sth->execute($questions[$i][0])){
        $num = 1;
        while(($ansID, $ansText, $correct) = $sth->fetchrow_array()){
            print <<"END_HTML";
            <tr>
            <td style="padding: 15px 30px"> 
                <label>
                    <input type="radio" name="questionAnswer" id="$ansID" value="$ansID" />
                    $num. $ansText
                </label>
            </td>
            </tr>
END_HTML
            $num++;
        }
    }

    print <<"END_HTML";
                </table>
                <div class="text-center" style="padding: 25px; font-weight: bold;">
                    $ans
                </div>
                <div class="tButton">
                    <input type="submit" name="submit" value="Submit"/>
                    <button type="button" id="prev" class="prev" onclick="prevQuestion($questions[$i-1][0])">&laquo; prev
                    <button type="button" id="next" class="next" onclick="nextQuestion($questions[$i+1][0])">next &raquo;
                </div>
            </form>
    </div>
END_HTML
    $qCount++;
}

Обновление

Вот дамп @questionsдо и после цикла.Я использовал жестко запрограммированный $i < 18, чтобы получить этот результат, но, как есть, он будет продолжаться, пока не закончится память.

[10/24/18 17:25:05] $VAR1 = [
          [
            9,
            'What are the key ingredients in the Original Killer Brownie&reg;?'
          ],
          [
            10,
            'Where do our Laura&#39;s Cookies come from?'
          ],
          [
            11,
            'How long is the shelf life on our artisan breads?'
          ],
          [
            12,
            'What happens to the bakery shrink (the items no longer fresh enough to sell)?'
          ],
          [
            13,
            'How many days a week are DLM artisan breads produced?'
          ],
          [
            14,
            'DLM artisan breads are produced in a ____ style oven.'
          ],
          [
            15,
            'How many items does Central Bakery produce for the stores?'
          ],
          [
            16,
            "TEST"
          ]
        ];
[10/24/18 17:25:05] $VAR1 = [
          [
            9,
            'What are the key ingredients in the Original Killer Brownie&reg;?'
          ],
          [
            10,
            'Where do our Laura&#39;s Cookies come from?'
          ],
          [
            11,
            'How long is the shelf life on our artisan breads?'
          ],
          [
            12,
            'What happens to the bakery shrink (the items no longer fresh enough to sell)?'
          ],
          [
            13,
            'How many days a week are DLM artisan breads produced?'
          ],
          [
            14,
            'DLM artisan breads are produced in a ____ style oven.'
          ],
          [
            15,
            'How many items does Central Bakery produce for the stores?'
          ],
          [
            16,
            "TEST"
          ],
          [],
          [],
          [],
          [],
          [],
          [],
          [],
          [],
          [],
          [],
          []
        ];

1 Ответ

0 голосов
/ 25 октября 2018

Проблема здесь:

<button type="button" id="next" class="next" onclick="nextQuestion($questions[$i+1][0])">next &raquo;

Выражение $questions[$i+1][0] будет автоматически оживлять элемент $questions[$i+1] в ссылку на массив, поскольку вы обращались к нему как единое целое.Таким образом, @questions будет иметь дополнительный элемент.Вы можете использовать прагму autovivification , чтобы предотвратить это, или проверить, определено ли $questions[$i+1] или, если $i < $#questions, перед его использованием.$#questions является ярлыком для последнего индекса массива @questions.Примечание: у вас может быть похожая проблема со строкой prevQuestion и индексом 0, хотя индекс -1 будет просто обращаться к последнему элементу массива.

Другой угол этой проблемы - ваш цикл C в стиле forзависит от размера @questions на каждой итерации.Альтернативой является использование цикла perish foreach .

foreach my $i (0..$#questions) {
  # everything else the same
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...