Answers are at the end of the article.
What value is returned by a lone return
statement?
The empty list value ()
.
The undefined value in scalar context, and the empty list
value ()
in list
context.
The result of the last evaluated expression in that subroutine’s block.
The undefined value.
What’s the difference between /^Foo/s
and /^Foo/?
The first would allow the match to cross newline boundaries.
The first would match Foo
other than at the start of the
record if the previous match were /^Foo/gcm
, new in the 5.004
release.
The second would match Foo
other than at the start of the
record if $*
were set.
There is no difference because /s
only affects whether dot can match
newline.
What does length(%HASH)
produce if you have 37 random keys in a newly created hash?
5
37
74
2
What does read
return at
end of file?
0
“0 but true”
“ ”
undef
How do you produce a reference to a list?
[ @array ]
($s, @a, %h,
&c)
You can’t produce a reference to a list.
@array
Why aren’t Perl’s patterns regular expressions?
Because Perl allows both minimal matching and maximal matching in the same pattern.
Because Perl uses a non-deterministic finite automaton rather than a deterministic finite automaton.
Because Perl patterns can have look-ahead assertions and negations.
Because Perl patterns have backreferences.
Why doesn’t Perl have overloaded functions?
Because you can inspect the argument count, return context, and object types all by yourself.
It does, along with overloaded operators as well as overridden functions and methods.
Because Perl doesn’t have function prototypes.
Because it’s too hard.
Why is it hard to call this function: sub y { “because” }
?
It’s not.
Because y
is a
predefined function.
Because it has no prototype.
Because y
is a kind of
quoting operator.
How do you print out the next line from a filehandle with all its bytes reversed?
print reverse scalar
<FH>
print scalar reverse scalar
<FH>
print scalar reverse
<FH>
print reverse
<FH>
When would local $_
in a
function ruin your day?
When your caller was in the middle of a while(<>)
loop.
When your caller was in the middle of a while(m//g)
loop.
When $_
was imported
from another module.
When your caller was in the middle of a foreach(@a)
loop.
Which of these is a difference between C++ and Perl?
C++ can have objects whose data cannot be accessed outside its class, but Perl cannot.
C++ supports multiple inheritance, but Perl does not.
C++ will not call destructors on objects that go out of scope if a reference to that object still exists, but Perl will.
Perl can have objects whose data cannot be accessed outside its class, but C++ cannot.
Assuming both a local($var)
and a my($var)
exist, what’s the
difference between ${var}
and
${“var”}
?
${var}
is the package
variable $var
, and ${“var”}
is the scoped variable
$var
.
There is no difference.
${var}
is a package
variable $var
, and ${“var”}
a global variable $var
.
${var}
is the lexical
variable $var
, and ${“var”}
is the dynamic variable
$var
.
If EXPR is an arbitrary expression, what
is the difference between $Foo::{
EXPR}
and *{“Foo::”
.EXPR}
?
The second is disallowed under use strict “refs”
.
The first happens at runtime, the second at compile time.
One is just a regular hash, the other a typeglob access for a strangely named variable.
The first can create new globs dynamically, but the second cannot.
Assuming $_
contains HTML,
which of the following substitutions will remove all tags in
it?
s/<.*>//g;
s/<.*?>//gs;
s/</?[A-Z]w*(?:s+[A-Z]w*(?:s*=s*(?:([″′]).*?1|[w-
.]+))?)*s*>//gsix;
You can’t do that.
What does new
$cur->{LINK}
do? (Assume the current package has no
new
function of its own.)
$cur->new()->{LINK}
new($cur->{LINK})
$cur ?
($cur->{LINK}->new()) :
(new()->{LINK})
$cur->{LINK}->new()
What does $result = f() ..
g()
really return?
It produces a syntax error.
True if and only if both f()
and g()
are true, or if f()
and g()
are both false, but returns false
otherwise.
False so long as f()
returns false, after which it returns true until g()
returns true, and then starts the
cycle again.
The last number from the list of numbers returned in the
range between f()
’s return
value and g()
’s.
What happens when you return a reference to a private variable?
The underlying object is silently copied.
Nothing bad—it just works.
The compiler doesn’t let you.
You get a core dump later when you use it.
How do you give functions private variables that retain their values between calls?
Include them as extra parameters in the prototype list, but don’t pass anything in at that slot.
Use localized globals.
Create a scope surrounding that sub that contains lexicals.
Perl doesn’t support that.
What happens to objects lost in “unreachable” memory, such as the object returned by $Ob->new()
in this block?
{ my $ap; $ap = [ $Ob->new(), $ap ]; }
Their destructors are called when the memory becomes unreachable.
Their destructors are never called.
Perl doesn’t support destructors.
Their destructors are called when that interpreter thread shuts down.
What does Perl do if you try to exploit the execve(2)
race condition involving setuid
scripts?
Sends mail to root and exits.
Runs the fake script with setuid permissions.
Runs the fake script, but without setuid permissions.
Reboots your machine.
b. This way functions that wish to return failure can just use a simple return without worrying about the context in which they were called.
If you answered a: That would only be true in list context.
If you answered c: That’s what happens when the function
ends without return
being used
at all.
If you answered d: That would only be true in scalar context.
c. The deprecated $*
flag
does double duty, filling the roles of both /s
and /m
. By using /s
, you suppress any settings of that
spooky variable, and force your carets and dollars to match only
at the ends of the string and not at the ends of the line as
well—just as they would if $*
weren’t set at all.
If you answered a: /s
only makes a dot able to match a newline, and then only if the
string actually has a newline in it.
If you answered b: Although the /c
modifier is indeed new as of 5.004
(and is used with /g
), this has
no particular interaction with /s
.
If you answered d: /s
does more than that.
a. length
is a built-in
function prototyped as sub
length($)
, and that scalar prototype silently changes
aggregates into radically different forms. The scalar sense of a
hash is false (0
) if it’s
empty, otherwise it’s a string representing the fullness of the
hash buckets, like 18/32
or
39/64
. The length of that
string is likely to be 5. Likewise, length(@a)
would be 2 if there were 37
elements in @a
.
If you answered b: length
%HASH
is nothing at all like scalar keys %HASH
, which is a good bit
more useful.
If you answered c: length
%HASH
is nothing at all like the size of the list of all
the keys and values in %HASH
.
If you answered d: You probably think it decided there were 37 keys, and that length(37) is 2. Close, but not quite.
a. A defined (but false) 0 value is the proper indication of
the end of file for read
and
sysread
.
If you answered b: You’re thinking of the ioctl
and fcntl
functions, which return this when
the C version returned 0, reserving undef
for when the C version returns -1.
For example, fcntl(STDIN,F_GETFL,1)
returns “0 but
true” depending on whether and how standard input has been
redirected. (The F_GETFL
flag
can be loaded from the Fcntl.pm module.)
If you answered c: That’s a string of length 1 consisting of
the NULL character, whose ord
is 0, which is false. The string, however, is true. read
doesn’t return strings, but rather
byte-counts.
If you answered d: That would signal an I/O error, not
normal end of file. The circumfix operator <>
returns undef
when it reaches end of file, but a
normal read does not.
c. A list is not an array, although in 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.
If you answered a: That makes a reference to a newly
allocated anonymous array, and populates it with a copy of the
contents of @array
.
If you answered b: The backslash operator is distributive
across a list, and produces a list in return, this being ($s, @a, \%h, &c
) in list context.
In scalar context, it’s a strange way to get a reference to the
function &c
.
If you answered d: @array
is not a list, but an array.
d. 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]+)c1/
requires the state machine
to remember old states, and thus disqualifies such patterns from
being regular expressions in the classic sense of the term.
If you answered a: The mere presence of minimal and maximal repetitions does not disqualify a language from being regular.
If you answered b: 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.
If you answered c: The (?=foo
) and (?!foo
) constructs no more violate the
language’s regularity than ^
and $
, which are also
zero-width statements.
a. In Perl, the number of arguments is available to a
function via the scalar sense of @_
, the return context is available via
wantarray
, and the types of the
arguments via ref
(if they’re
references) and simple pattern matching like /^d+$/
(otherwise). In low-level
languages like C++, where you can’t do this, you must resort to
overloading of functions.
If you answered b: Actually, Perl does support overloaded
operators via use overload
,
overridden functions as in use Cwd
qw!chdir!
, and overridden methods via inheritance and
polymorphism. It just doesn’t support functions automatically
overloaded on parameter signature or return type. Not that such
isn’t longed for.
If you answered c: Perl actually does have function prototypes; however, this isn’t used for the traditional sort of prototype checking, but rather for creating functions that exactly emulate Perl’s built-ins, which can implicitly force context conversion or pass-by-reference without the caller being aware.
If you answered d: Just because it’s hard isn’t likely to rule out something from being implemented—someday.
d. The y///
operator is
the sed-savvy synonym for tr
.
That means y(3)
would be like
tr(3)
, which would be looking
for a second string, as in tr/a-z/A-Z/,
tr(a-z)(A-Z)
, or tr[a-z][A-Z]
.
If you answered a: Most people don’t call functions with
ampersands anymore. If they did, as in &y()
, it wouldn’t be so hard.
If you answered b: y
isn’t really a function, per se. If it were, you would never see
y!abc!xyz!
, since proper
functions do not like getting banged on that way.
If you answered c: Functions don’t require prototypes in Perl.
b. Surprisingly enough, you have to put both the reverse
and the <FH>
into scalar context
separately for this to work.
If you answered a: Although scalar
<FH>
did retrieve just the next line, the reverse
is still in the list context
imposed on it by print, so it takes its list of one element and
reverses the order of the list, producing exactly the next line.
An expensive way of writing print scalar
<FH>
.
If you answered c: Although the first use of scalar inhibits
the list context being imposed on reverse
by print
, it doesn’t carry through to
change the list context that reverse
is imposing on <FH>
. So reverse
catenates all its arguments and
does a byte-for-byte flip on the resulting string.
If you answered d: That reads all lines in FH
, then reverses that list of lines and
passes the resulting reversed list off to print. This is actually
a very useful thing, and simulates tail
-r
behavior but without the annoying buffer limitations
of that utility. Nonetheless, it’s not what we want.
b. The /g
state on a
global variable is not protected with local. That’ll teach you to
stop using locals. Too bad $_
can’t be the target of a my
—yet.
If you answered a: However, if you do a while(<>)
and forget to first
localize $_
, you’ll hurt
someone above you. That’s because even though foreach
implicitly localizes $_
, the while
(<>)
construct does not.
If you answered c: Doing a local
on an imported variable is not
harmful. Of course, in the case of $_
, it’s virtually unnecessary, since
$_
is always forced to mean the
version in the main package, that is, $main::_
.
If you answered d: This looks close to the bizarre phenomenon known as variable suicide, but that only occurs in ancient Perl versions.
d. Perl can use closures with unreachable private data as
objects, and C++ doesn’t support closures. Furthermore, C++ does
support pointer arithmetic via int *ip =
(int*)&object
, allowing you to look all over the
object. Perl doesn’t have pointer arithmetic. It also doesn’t
allow #define private public
to
change access rights to foreign objects. On the other hand, once
you start poking around in /dev/mem
, no one is safe.
If you answered b: Both support multiple inheritance.
If you answered c: Exchange “Perl” and “C++” in that answer, and you would be telling the truth. C++ is too primitive to know when an object is no longer in use, because it has no garbage collection system. Perl does.
d. Odd though it appears, this is how it works. Note that
because the second is a symbol table lookup, it is disallowed
under use strict “refs”
. The
words global, local, package, symbol table, and dynamic all refer
to the kind of variables that local
affects, whereas the other sort,
those governed by my
, are
variously known as private, lexical, or scoped variables.
If you answered a: Try again. You’re close.
If you answered b: One is the scoped variable, the other the package variable. Which is which, though?
If you answered c: There is no difference between a package variable and a global variable. All package variables are globals, and vice versa.
a. Dereferencing a string with *{“STR”}
is forbidden under the refs
stricture, although *{STR}
is allowed. This is similar in
spirit to the way ${“STR”}
is
always the symbol table variable, while ${STR}
may be the lexical variable. If
it’s not a bareword, you’re playing with the symbol table in a
particularly dynamic fashion.
If you answered b: Assuming that the expressions don’t get
resolved at compile time, this all has to wait until run time.
Something like *Foo::varname
,
however, would be looked up at compile time.
If you answered c: The %Foo::
hash is always the symbol table
associated with package Foo; such a hash can hardly be called
regular. Both versions actually refer to the same typeglob,
although somewhat differently.
If you answered d: Although you can get the symbol table of
the Foo
package via the
%Foo::
hash, you cannot
usefully generate new typeglobs (symbols) this way. You could copy
old ones into that slot, though, effectively doing the Exporter’s
job by hand.
d. If it weren’t for HTML comments, improperly formatted
HTML, and tags with interesting data like <SCRIPT>
, you could do this. Alas,
you cannot. It takes a lot more smarts, and quite frankly, a real
parser.
If you answered a: As written, the dot will not cross
newline boundaries, and the star is being too greedy. If you add a
/s
, then yes, it will remove
all tags—and a great deal else besides.
If you answered b: It is easy to construct a tag that will
cause this to fail, such as <IMG
SRC=‘foo.gif’ ALT=“> ”>
.
If you answered c: For a good deal of HTML, this will
actually work, but it will fail on cases with annoying comments,
poorly formatted HTML, and tags like <SCRIPT>
and <STYLE>
, which can contain things
like while (<FH>) {}
without those being counted as tags. Comments that will annoy you
include <!-- <foo bar =
“-->”>
which will remove characters when it
shouldn’t; it’s just a comment followed by “>
. And even something like <!-- <foo bar = ”-->
most
browsers will get right, but the substitution will not. And if you
have improper HTML, you get into even more trouble, like this:
<foo bar = “bleh” @> text text text
<foo bar = “bleh”>
. Here, the .*?
will gobble up much more than you
thought it would.
a. The indirect object syntax only has a single token
lookahead. That means if new
is
a method, it only grabs the very next token, not the entire
following expression. This is why new
$obj[23] arg
doesn’t work, as well as why print $fh[23] “stuff
”
doesn’t work.
Mixing notations between the OO and IO notations is perilous. If
you always use arrow syntax for method calls, and nothing else,
you’ll never be surprised.
If you answered b: If the current package did in fact have
its own new
function, then this
would be the right answer, but for the wrong reasons. Within a
class, it might appear to make no difference since the new
subroutine would get its argument in
$_[0]
whether it’s called as a
function or a method. However, a method call can use inheritance,
while a function call never does. That means esoteric overridden
new
methods would be duped out
of calling their derived class’ constructor first, and we wouldn’t
want that to happen, would we?
If you answered c: Perl may be crazy, but it’s not quite that crazy. Yet.
If you answered d: Just because it looks like a unary function doesn’t mean a method call parses like one. You just want it to work this way. If you want that, write that.
c. This is scalar context, not list context, so we have the
bistable flip-flop range operator famous in parsing of mail
messages, as in $in_body = /^$/ ..
eof()
. Except for the first time f()
returns true, g()
is entirely ignored, and f()
will be ignored later when g()
is evaluated. Double dot is the
inclusive range operator; f()
and g()
will both be evaluated
on the same record. If you don’t want that to happen, the
exclusive range operator, triple dots, can be used instead. For
extra credit, describe this: $bingo = (
a() .. b() ) … ( c() .. d() );
If you answered a: You’d be amazed at how many things in Perl don’t cause syntax errors.
If you answered b: That sounds more like a negated logical
xor. A logical xor is !$a !=
!$b
, so you’ve just described !$a == !$b
. Interesting, and perhaps
even useful, but unrelated to ..
, our scalar range operator.
If you answered d: That might work in list context, but
never in scalar. The list operator ..
is a completely different creature
than the scalar one. They’re just spelled the same way, kind of
like when you can the rusty old can down by the guys’ can just
because you can. Context, as always, is critical.
b. Perl keeps track of your variables, whether dynamic or otherwise, and doesn’t free things before you’re done using them.
If you answered a: 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.
If you answered c: 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.
If you answered d: Perl is not C or C++.
c. 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 private variable. The $i
variable will not be deallocated when its block goes away because
the next_i
and last_i
subroutines need to be able to
access it.
If you answered a: Perl is not the Korn shell, nor anything like it. If you tried this, your program probably wouldn’t even compile.
If you answered b: 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.
If you answered d: It would be difficult to keep private state in a function otherwise.
d. 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.
If you answered a: Under the current implementation, the
reference-counted garbage collection system won’t notice that the
object in $ap
’s array cannot be
reached, because the array reference itself never has its
reference count go to zero.
If you answered b: That would be very bad, because then you could have objects whose class-specific cleanup code didn’t get called ever.
If you answered c: A class’s DESTROY
function, or that of its base
classes, is called for any cleanup. It is not expected to
deallocate memory, however.
a. It has been said that all programs advance to the point of being able to automatically read mail. While not quite there yet (well, without loading a module), Perl will at least automatically send it.
If you answered b: That would be bad. Very Bad. What do you think we are? A shell or something?
If you answered c: It would be improper to run anything at all in the face of such naughtiness.
If you answered d: An appealing idea, though, isn’t it? After all, Perl does possess super(user)powers at this point. You just never know what it might do. In the interests of courtesy, though, Perl stays out of your power supply just as it stays out of your living room.