Perl数组被未知来源修改

时间:2018-10-24 21:08:22

标签: perl multidimensional-array

我相信我遇到了一个错误,但是想确保我不仅仅是在错过一些东西。我的实习生正在一个网站上工作,该网站将对可变数量的问题和可变数量的答案进行测试,以帮助员工完成培训。我们将问题存储在2D数组中,其中包含问题ID和问题文本。我们遍历该数组为每个问题创建div,将第一个问题隐藏起来,然后使用该问题ID在循环中获取该问题的答案。

我们遇到的是,当require 'benchmark' dir = Dir[Dir.pwd + '/*']; nil filetypes = %w(flac vw); nil 10.times { puts Benchmark.measure { 10000.times { dir.each { |filename| nil if filename.end_with?(*filetypes) } } } } 11.182205 0.014303 11.196508 ( 11.210042) 11.154286 0.011573 11.165859 ( 11.178611) 11.081012 0.009853 11.090865 ( 11.098028) 11.084294 0.009361 11.093655 ( 11.101870) 10.990442 0.007118 10.997560 ( 11.002036) 11.044119 0.009284 11.053403 ( 11.058608) 11.072604 0.009114 11.081718 ( 11.087941) 11.127151 0.009354 11.136505 ( 11.143270) 11.172101 0.012262 11.184363 ( 11.195138) 11.126791 0.010767 11.137558 ( 11.145617) 循环到达最后一个索引时,一个空元素被推到for上。这会使@questions的结果增加一,并且该循环无限期地重复。我们无法确定的是是什么导致空元素被推送到@questions?

scalar @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

1 个答案:

答案 0 :(得分:5)

问题在这里:

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

表达式$questions[$i+1][0]autovivify元素$questions[$i+1]放入数组引用中,因为您像访问元素一样。因此@questions将具有一个额外的元素。您可以使用autovivification编译指示来防止这种情况的发生,或者在使用之前检查$questions[$i+1]是否已定义或是否$i < $#questions$#questions是数组@questions的最后一个索引的快捷方式。注意:prevQuestion行和索引0可能存在类似的问题,尽管索引-1只会访问数组的最后一个元素。

另一个问题是,您的C风格的for循环取决于每次迭代时@questions的大小。另一种方法是使用Perlish foreach loop

foreach my $i (0..$#questions) {
  # everything else the same
}