我相信我遇到了一个错误,但是想确保我不仅仅是在错过一些东西。我的实习生正在一个网站上工作,该网站将对可变数量的问题和可变数量的答案进行测试,以帮助员工完成培训。我们将问题存储在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 #$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])">« prev
<button type="button" id="next" class="next" onclick="nextQuestion($questions[$i+1][0])">next »
</div>
</form>
</div>
END_HTML
$qCount++;
}
转储。我使用了一个硬编码的@questions
来获得此结果,但是按原样,它会一直持续到内存耗尽。
$i < 18
答案 0 :(得分:5)
问题在这里:
<button type="button" id="next" class="next" onclick="nextQuestion($questions[$i+1][0])">next »
表达式$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
}