[courtesy cc of this posting sent to cited author via email]
:Freidl explains them in glorious detail and emphasizes the "/m affects
:*only* ^$, /s affects *only* ." tack which I took in my previous message.
:However, all the same semantics are there in perlre.
But that's false: /s affects ^ and $ as well, insulating them from
unpleasant surprises out of $* settings.
--tom
#!/usr/bin/perl -00
use strict;
use FileHandle;
$| = 1;
my $DELAY = 2;
my $RANDOMIZE = 1;
while (<DATA>) {
next if /===/;
my %record;
(undef, %record) = split /^([^:\s]+):\s*/m;
else { die "unknown record $_" }
Quote:
}
rand_questions();
exit;
show_full_quiz();
####################################
sub rand_questions {
for (my $qnum = 0; $qnum < $#questions; $qnum++) {
system('clear');
$q = $questions[$qnum];
question("Q".(1+$qnum), $q->{Question});
my $anum = 'a';
answer($anum++, $a->{Answer});
}
delay(5);
print "\nANSWERS:\n\n";
for ( my $i = 0; $i <= $#answers; $i++ ) {
my $a = $answers[$i];
explain( ( 'a' .. 'z' )[$i], $a->{Correct} . $a->{Why} );
print "\n";
delay(2 + length($a->{Why})/50);
}
delay(5);
}
Quote:
}
sub delay {
my $count = shift;
sleep(1 + $DELAY * $count);
Quote:
}
sub rand_question {
system('clear');
question('Q', $q->{Question});
my $anum = 'a';
answer($anum++, $a->{Answer});
}
delay(3);
print "\nANSWERS:\n\n";
for ( my $i = 0; $i <= $#answers; $i++ ) {
answer( ( 'a' .. 'z' )[$i],
$answers[$i]{Correct} .
$answers[$i]{Why} );
print "\n";
delay(1);
}
print "\n";
delay(5);
Quote:
}
sub show_full_quiz {
my $qnum = '01';
fwrite ($qnum++, $q->{Question});
my $anum = 'a';
fwrite(' '.$anum++.':', $a->{Answer});
}
print "\n";
}
Quote:
}
sub scramble {
srand(time() ^ ($$ + ($$ << 15)));
Quote:
}
sub fwrite {
sub question { STDOUT->format_name("Question"); &fwrite; }
sub answer { STDOUT->format_name("Answer"); &fwrite; }
sub explain { STDOUT->format_name("Explain"); &fwrite; }
$num, $text
~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$text
.
format Answer =
$num, $text
~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$text
.
$num, $text
~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$text
.
write;
Quote:
}
__DATA__
Question: How do you produce a reference to a list?
Type: References
Difficulty: 6/7 (Hard)
Correct: No.
Correct: No.
Why: That makes a reference to a newly allocated anonymous
array, and populates it with a copy of the contents
Correct: No.
Why: The backslash operator is distributive across a list, and
Well. In list context. In scalar context, it's a strange
way to get a reference to the function &c.
Answer: You can't.
Correct: Yes.
Why: A list is not an array, although is many places one may be
used for the other. An array has an AV allocated, whereas a
list is just some values on a stack somewhere. You cannot
alter the length of a list, for example, any more than
you could alter a number by saying something like 23++.
While an array contains a list, it is not a list itself.
========================================================================
Question: What happens when you return a reference to a private variable?
Type: References
Difficulty: 4/7 (Medium)
Answer: You get a core dump later when you use it.
Correct: No.
Why: Perl is not C or C++.
Answer: The underlying object is silently copied.
Correct: No.
Why: Even though the reference returned is for all intents
and purposes a copy of the original (Perl uses return
by reference), the underlying referent has not changed.
Answer: The Right Thing (tm).
Correct: Yes.
Why: Perl keeps track of your variables, whether dynamic or
otherwise, and doesn't free things before you're done using
them.
Answer: The compiler doesn't let you.
Correct: No.
Why: Perl seldom stops you from doing what you want to do,
and tries very hard to do what you mean to do. This
is one of those cases.
========================================================================
Question: Why aren't Perl's patterns regular expressions?
Type: Regular expressions
Difficulty: 3/7 (Medium)
Answer: Because Perl patterns have backreferences.
Correct: Yes.
Why: A regular expression by definition must be
able to determine the next state in the finite
automaton without requiring any extra memory
to keep around previous state. A pattern /([ab]+)c\1/
requires the state machine to remember old
states, and thus disqualifies such patterns
as being regular expressions in the classic sense
of the term.
Answer: Because Perl allows both minimal matching and maximal
matching in the same pattern.
Correct: No.
Why: The mere presence of minimal and maximal repetitions
does not disqualify a language from being "regular".
Answer: Because Perl uses a non-deterministic finite automaton
rather than a deterministic finite automaton.
Correct: No.
Why: Both NFAs and DFAs can be used to solve regular
expressions. Given an NFA, a DFA for it can be constructed,
and vice versa. For example, classical grep uses an NFA,
while classical egrep a DFA. Whether a pattern matches
a particular string doesn't change, but where the match
occurs may. In any case, they're both regular. However,
an NFA can also be modified to handle backtracking, while
a DFA cannot.
Answer: Because Perl patterns can have look-aheads assertions
and negations.
Correct: No.
Why: The `(?=foo)' and `(?!foo)' constructs no more violate
whether the language is regular than do `^' and `$',
which are also zero-width statements.
========================================================================
Question: What happens to objects lost in "unreachable" memory,
such as the object returned by Ob->new() in
`{ my $ap; $ap = [ Ob->new(), \$ap ]; }' ?
Type: Objects
Difficulty: 4/7 (Medium)
Answer: Their destructors are called when that interpreter thread
shuts down.
Correct: Yes.
Why: When the interpreter exits, it first does an exhaustive
search looking for anything that it allocated. This allows
Perl to be used in embedded and multithreaded applications
safely, and furthermore guarantees correctness of object
code.
Answer: Their destructors are called when the memory becomes unreachable.
Correct: No.
Why: Under the current implementation, the reference-counted
garbage collection system will not notice that the object
in $ap's array cannot be reached, because the array reference
itself never has its reference count go to zero.
Answer: Their destructors are never called.
Correct: No.
Why: That would be very bad, because then you could have objects
whose class-specific cleanup code didn't get called ever.
Answer: Perl doesn't support destructors.
Correct: No.
Why: A class's DESTROY function, or that of its base classes,
is called for any cleanup. It is not expected to deallocate
memory, however.
========================================================================
Question: How do you give functions private variables that
retain their values between calls?
Type: Subroutines, Scoping
Difficulty: 5/7 (Medium)
Answer: Perl doesn't support that.
Correct: No.
Why: It would be difficult to keep private state in a
function otherwise.
Answer: Include them as extra parameters in the prototype list,
but don't pass anything in at that slot.
Correct: No.
Why: Perl is not the Korn shell, nor anything like that.
If you tried this, your program probably wouldn't
even compile.
Answer: Use localized globals.
Correct: No.
Why: The local() operator merely saves the old value of a global
variable, restoring that value when the block in which the
local occurred exits. Once the subroutine exits, the
temporary value is lost. Before then, other functions
can access the temporary value of that global variable.
Answer: Create a scope surrounding that sub that contains lexicals.
Correct: Yes.
Why: Only lexical variables are truly private, and they will
persist even when their block exits if something still
cares about them. Thus:
{ my $i = 0; sub next_i { $i++ } sub last_i { --$i } }
creates two functions that share a
...
read more »