2012/05/21

The Labs.Com Issue_08_Quiz
Last update 1999/02/20

TPJ: Issue_08_Quiz

This is a collection of programs published by The Perl Journal. You can download all source-code also from TPJ: Programs.
Issue_08_Quiz
1. quiz-answers
Download quiz-answers

 #!/usr/bin/perl -00 
 my $RANDOMIZE = 1; 
 my @questions; 
  
 while (<DATA>) { 
     next if /===/; 
     my %record; 
     (undef, %record) = split /^([^:\s]+):\s*/m; 
     for (@record{keys %record}) { s/\s+/ /g } 
     if   ($record{Question}) { push @questions, \%record}  
     elsif($record{Answer}  ) { push @{ $questions[-1]{Answers} }, \%re\ 
 cord} 
     else                     { die "unknown record $_" }  
 }  
  
 my $qnum = '01'; 
 for $q (scramble(@questions)) { 
     fwrite ($qnum++, $q->{Question}); 
     my $anum = 'a'; 
     for $a ( scramble(@{$q->{Answers}}) ) { 
         fwrite($anum++, $a->{Answer}); 
     }  
     print "\n"; 
 }  
  
 sub scramble { 
     return @_ unless $RANDOMIZE; 
     my @list; 
     srand(time() ^ ($$ + ($$ << 15))); 
     push(@list, splice (@_, rand @_, 1)) while @_; 
     return @list; 
 }  
  
 sub fwrite { 
     ($num, $text) = @_; 
 format =  
 @>.  ^<<<<<<<<<<<<<<<&\ 
 lt;<<<<<<<<<<<<<<<<<\ 
 ;<<<<<<<<<<<<<<<<<&\ 
 lt;<<<<<<<<<<<<<< 
 $num, $text 
   ~~ ^<<<<<<<<<<<<<<<<\ 
 <<<<<<<<<<<<<<<<<&l\ 
 t;<<<<<<<<<<<<<<<<<\ 
 <<<<<<<<<<<<<< 
       $text 
 . 
  
     write; 
  
 }  
 __DATA__ 
 Question:   How do you produce a reference to a list? 
 Type:       References 
 Difficulty: 6/7 (Hard) 
 Answer:     \@array 
 Correct:    No. 
 Why:        @array is not a list, but an array.   
 Answer:     [ @array ] 
 Correct:    No. 
 Why:        That makes a reference to a newly allocated anonymous 
             array, and populates it with a copy of the contents 
             of @array. 
 Answer:     \($s, @a, %h, &c) 
 Correct:    No. 
 Why:        The backslash operator is distributive across a list, and 
             produces a list in return, this being (\$s, \@a, \%h, \&c)\ 
 . 
             Well.  In list context.  In scalar context, it's a strange 
             way to get a reference to the function &c. 
  
 Answer:     You can't take a reference to a list. 
 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 vari\ 
 able? 
 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:            Nothing bad -- it just works. 
 Correct:    Yes. 
 Why:            Perl keeps track of your variables, whether dynamic or 
             otherwise, and doesn't free things before you're done usin\ 
 g  
             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 maxim\ 
 al 
             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 automa\ 
 ton 
             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 constructe\ 
 d, 
             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 assertio\ 
 ns 
             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 exhaustiv\ 
 e  
             search looking for anything that it allocated.  This allow\ 
 s 
             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 become\ 
 s unreachable. 
 Correct:    No. 
 Why:            Under the current implementation, the reference-counte\ 
 d  
             garbage collection system will not notice that the object 
             in $ap's array cannot be reached, because the array refere\ 
 nce 
             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 ob\ 
 jects 
             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 classe\ 
 s, 
             is called for any cleanup.  It is not expected to dealloca\ 
 te 
             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 l\ 
 ist, 
             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 g\ 
 lobal 
             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 l\ 
 exicals. 
 Correct:    Yes. 
 Why:            Only lexical variables are truly private, and they wil\ 
 l 
             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 next_i and last_i need to be able to access i\ 
 t. 
 ======================================================================\ 
 == 
 Question:   What value is returned by a lone `return;' statement? 
 Type:            Subroutines, Syntax 
 Difficulty: 3/7 (Medium) 
 Answer:            The undefined value. 
 Correct:    No. 
 Why:            That would only be true in scalar context. 
 Answer:            The empty list value (). 
 Correct:    No. 
 Why:            That would only be true in list context. 
 Answer:            The undefined value in scalar context, and 
             the empty list value () in list context. 
 Correct:    Yes. 
 Why:            This way functions that wish to return failure 
             can just use a simple return without worrying about 
             the context in which they were called. 
  
 Answer:            The result of the last evaluated expression in that 
             subroutine's block. 
 Correct:    No. 
 Why:            That's what happens when the function ends without 
             return being used at all. 
  
 ======================================================================\ 
 == 
  
 Question:     Assuming $_ contains HTML, which of 
             the following substitutions will remove all tags in it? 
 Type:            Regular Expressions, WWW 
 Difficulty: 6/7 (Hard) 
 Answer:            You can't do that. 
 Correct:    Yes. 
 Why:            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. 
  
 Answer:            s/<.*>//g; 
 Correct:    No. 
 Why:            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. 
 Answer:            s/<.*?>//gs; 
 Correct:    No. 
 Why:            It is easy to construct a tag that will cause this to \ 
 fail, 
             such as the common `<IMG SRC='foo.gif' ALT="> ">'\ 
  tag. 
  
 Answer:            s/<\/?[A-Z]\w*(?:\s+[A-Z]\w*(?:\s*=\s*(?:(["']).\ 
 *?\1|[\w-.]+))?)*\s*>//gsix; 
 Correct:    No. 
 Why:            For a good deal of HTML, this will actually work, but 
             it will fail on cases with annoying comments, poorly forma\ 
 tted 
             HTML, and tags like <SCRIPT> and <STYLE>, whic\ 
 h can contain 
             things like `while (<FH>) {}' without those being co\ 
 unted 
             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 th\ 
 is: 
                     <!-- <foo bar = "--> 
             Most browsers will get right, but the substitution will no\ 
 t. 
             And if you have improper HTML, you get into even more 
             trouble, like this: 
                 <foo bar = "bleh" @> 
                 text text text 
                 <foo bar = "bleh"> 
             in which case the .*? will gobble up way more than you 
             thought it would. 
  
 ======================================================================\ 
 == 
  
 Question:   Assuming both a local($var) and a my($var) exist, 
             what's the difference between ${var} and ${"var"}?  
 Type:            Scope 
 Difficulty: 5/7 (Medium) 
 Answer:            ${var} is the lexical variable $var, and  
             ${"var"} is the dynamic variable $var. 
 Correct:    Yes. 
 Why:            Odd though it appears, this is how it works.  Note tha\ 
 t 
             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 knows as private, lexical, or scoped 
             variable. 
 Answer:            ${var} is the package variable $var, and  
             ${"var"} is the scoped variable $var. 
 Correct:    No. 
 Why:            Try again.  You're close. 
  
 Answer:            There is no difference. 
 Correct:    No. 
 Why:            One is the scoped 
             variable, the other the package variable.  Which is 
             which though? 
  
 Answer:            ${var} is a package variable $var, and ${"var"}  
             a global variable $var. 
 Correct:    No. 
 Why:            There is no difference between a package variable and 
             a global variable.  All package variables are globals, 
             and vice versa. 
 ======================================================================\ 
 == 
 Question:   Which of these is a difference between C++ and Perl? 
 Type:       Objects, Scope, C++ 
 Difficulty: 6/7 
 Answer:            Perl can have objects whose data cannot be accessed 
             outside its class, but C++ cannot. 
 Correct:    Yes. 
 Why:            Perl can use closures with unreachable private data as 
             objects, and C++ doesn't support closures.        Furtherm\ 
 ore, C++ 
             does support pointer arithmetic via `int *ip = (int*)&obje\ 
 ct', 
             allowing you do look all over the object.  Perl doesn't ha\ 
 ve 
             pointer arithmetic.  It also doesn't allow `#define privat\ 
 e 
             public' to change access rights to foreign objects.  On  
             the other hand, once you start poking around in /dev/mem, 
             no one is safe. 
 Answer:            C++ can have objects whose data cannot be accessed 
             outside its class, but Perl cannot. 
 Correct:    No. 
 Why:            See the correct answer for why. 
  
 Answer:            C++ supports multiple inheritance, but Perl does no\ 
 t. 
 Correct:    No. 
 Why:            Both support multiple inheritance. 
  
 Answer:            C++ will not call destructors on objects that go ou\ 
 t 
             of scope if a reference to that object still exists, 
             but Perl will. 
 Correct:    No. 
 Why:            Exchange "Perl" and "C++" in that answer, and you woul\ 
 d 
             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. 
 ======================================================================\ 
 == 
 Question:   What does Perl do if you try to exploit the execve(2)  
             race involving setuid scripts? 
 Type:            Security, Folklore 
 Difficulty: 2/7 (Easy) 
  
 Answer:            Reboots your machine. 
 Correct:    No. 
 Why:            An appealing idea, though, isn't it?  After all, Perl \ 
 does 
             possess super(user)powers at this point.  You just never k\ 
 now  
             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. 
  
 Answer:            Sends mail to root and exits. 
 Correct:    Yes. 
 Why:            It has been said that all programs advance to the 
             point of being able to automatically read mail.  While  
             not quite at that point (well, without having a module 
             loaded), Perl does at least automatically send it. 
 Answer:            Runs the fake script with setuid perms. 
 Correct:    No. 
 Why:            That would be bad.  Very Bad.  What do you think we 
             are?  A shell or something? 
  
 Answer:            Runs the fake script, but without setuid perms. 
 Correct:    No. 
 Why:            It would be improper to run anything at all in the  
             face of such naughtiness. 
 ======================================================================\ 
 == 
 Question:   How do you print out the next line from a filehandle 
             with all its bytes reversed? 
 Type:            I/O, Built-in Functions, Context 
 Difficulty: 5/7 
  
 Answer:            print reverse <FH> 
 Correct:    No. 
 Why:            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 for an answer to this question. 
 Answer:            print reverse scalar <FH> 
 Correct:    No. 
 Why:            Although `scalar <FH>' did retrieve just the nex\ 
 t 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>'. 
 Answer:            print scalar reverse scalar <FH> 
 Correct:    Yes. 
 Why:            Surprisingly enough, you have to put both the reverse \ 
 and 
             the <FH> into scalar context separately for this to \ 
 work. 
  
 Answer:            print scalar reverse <FH> 
 Correct:    No. 
 Why:            Although the first use of scalar inhibits the list con\ 
 text 
             being imposed on reverse by print, it doesn't carry throug\ 
 h 
             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. 
  
 ======================================================================\ 
 == 
  
 Question:   Why is it hard to call this function:  sub y { "because" } 
 Type:       User Functions, Operators 
 Difficulty: 4/7 (Medium) 
  
 Answer:            Because y is a kind of quoting operator. 
 Correct:    Yes. 
 Why:            The y/// operator is the sed-savvy synonym for tr///. 
             That means y(3) would be like tr(), 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]. 
 Answer:            It's not. 
 Correct:    No. 
 Why:            Most people don't call functions with ampersands anymo\ 
 re. 
             If they did, as in &y(), it wouldn't be so hard. 
  
 Answer:            Because y is a predefined function. 
 Correct:    No. 
 Why:            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. 
  
 Answer:            Because it has no prototype. 
 Correct:    No. 
 Why:            Functions don't require prototypes in Perl. 
  
 ======================================================================\ 
 == 
  
 Question:   What does `$result = f() .. g()' really return?     
 Type:            Operators 
 Difficulty: 5/7 (Medium) 
  
 Answer:            The last number from the list of numbers 
             returned in the the range between f()'s return  
             value and g()'s. 
 Correct:    No. 
 Why:            That might work in list context, but never in scalar. 
             The list `..' operator is a totally 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. 
 Answer:            Produces a syntax error. 
 Correct:    No. 
 Why:            You'd be amazed at how many things in Perl don't 
             cause syntax errors. 
  
 Answer:            True if and only if both f() and g() are true,  
             or if f() and g() are both false, but returns false  
             otherwise. 
 Correct:    No. 
 Why:            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. 
 Answer:            False so long as f() returns false, after 
             which it returns true until g() returns true,  
             and then starts the cycle again. 
 Correct:    Yes. 
 Why:            This is scalar not list context, so we have the bistab\ 
 le 
             flip-flop range operator famous in parsing of mail message\ 
 s, 
             as in `$in_body = /^$/ .. eof()'.  Except for the first 
             time f() returns true, g() is entirely ignored, and f() 
             will be ignored while g() 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() ); 
 ======================================================================\ 
 == 
 Question:   Why does Perl not have overloaded functions? 
 Type:            User Functions 
 Difficulty: 4/7 (Medium) 
 Answer:            Because it's too hard. 
 Correct:    No. 
 Why:            Just because it's hard isn't likely to rule out 
             something from being implemented -- someday. 
  
 Answer:            Because you can inspect the argument count,  
             return context, and object types all by yourself. 
 Correct:    Yes. 
 Why:            In Perl, the number of arguments is trivially availabl\ 
 e 
             to a function via the scalar sense of @_, the return 
             context via wantarray(), and the types of the 
             arguments via ref() if they're references and 
             simple pattern matching like /^\d+$/ otherwise. 
             In languages like C++ where you can't do this, you 
             simply must resort to overloading of functions. 
 Answer:            It does, along with overloaded operators as well 
             as overridden functions and methods. 
 Correct:    No. 
 Why:            Actually, Perl does support overloaded operators via `\ 
 use 
             overload', overridden functions as in `use Cwd qw!chdir!', 
             and overridden methods via inheritance and polyphormism. 
             It just doesn't support functions automatically overloaded 
             on parameter signature or return type.  Not that such 
             isn't longed  
 Answer:            Because Perl doesn't have function prototypes. 
 Correct:    No. 
 Why:            Perl actually does have function prototypes, but 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 of this. 
  
 ======================================================================\ 
 == 
  
 Question:   What does read() return at end of file? 
 Type:            I/O, Built-in Functions 
 Difficulty: 2/7 (Easy) 
  
 Answer:            undef 
 Correct:    No. 
 Why:            That would signal an I/O error, not normal end of file\ 
 . 
             The circumfix operator <> returns undef when it reac\ 
 hes end 
             of file, but a normal read does not. 
  
 Answer:            0 
 Correct:    Yes. 
 Why:            A defined (but false) 0 value is the proper indication\ 
  of the end of 
             file for read() and sysread().   
 Answer:     "0 but true" 
 Correct:    No. 
 Why:            You're thinking of the ioctl() and fcntl() functions w\ 
 hich 
             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 has been redirected. (The F_GETFL 
             flag was loaded from the Fcntl.pm module.) 
  
 Answer:            "\0" 
 Correct:    No. 
 Why:            That's a string of length 1 consisting of the ASCII NU\ 
 L 
             character, whose ord() is 0, which is false.  The string, 
             however, is true.  read() doesn't return strings, but 
             rather byte-counts. 
 ======================================================================\ 
 == 
 Question:   What does `new $cur->{LINK}' do?  (Assume the  
             current package has no new() function of its own.) 
 Type:            Objects 
 Difficulty: 6/7 (Hard) 
  
 Answer:            $cur->{LINK}->new() 
 Correct:    No. 
 Why:            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. 
 Answer:            $cur->new()->{LINK} 
 Correct:    Yes. 
 Why:            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' does't work, as well as 
             why `print $fh[23] "stuff\n"' does't work. 
             Mixing notations between the OO and IO notations is perilo\ 
 us.  If you always use 
             arrow syntax for method calls, and nothing else, you'll 
             not be surprised. 
 Answer:            new($cur->{LINK}) 
 Correct:    No. 
 Why:            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 argume\ 
 nt in $_[0] 
             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() methos would be 
             duped out of calling their derived class's constructor fir\ 
 st, 
             and we wouldn't want that to happen, now would we? 
 Answer:            $cur ? ($cur->{LINK}->new()) : (new()->{LI\ 
 NK}) 
 Correct:    No. 
 Why:            Perl may be crazy, but it's not quite that crazy.  Yet\ 
 . 
 ======================================================================\ 
 == 
 Question:   What's the difference between /^Foo/s and /^Foo/? 
 Type:            Regular Expressions 
 Difficulty: 5/7 (Medium) 
 Answer:            There is no difference because /s only affects whet\ 
 her dot 
             can match newline. 
 Correct:    No. 
 Why:            /s does more than that. 
  
 Answer:            The first would allow the match to cross newline bo\ 
 undaries. 
 Correct:    No. 
 Why:            /s only makes a dot able to cross a newline, and then \ 
    
             only if the string actually has a newline in it. 
 Answer:            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. 
 Correct:    No. 
 Why:            Although the /c modifier is indeed new as of 5.004 (an\ 
 d  
             is used with /g), this has no particular interaction with \ 
 /s. 
  
 Answer:            The second would match Foo other than at the start  
             of the record if $* were set. 
 Correct:    Yes. 
 Why:            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 ends of line as well -- just as 
             they would if $* weren't set at all. 
  
 ======================================================================\ 
 == 
  
 Question:   What does length(%HASH) produce if you have thirty-seven  
             random keys in a newly created hash? 
 Type:            Hashes, Built-in Functions, Context 
 Difficulty: 5/7 (Medium) 
 Answer:            2 
 Correct:    No. 
 Why:            You probably think it decided there were 37 keys, and 
             that length(37) is 2.  Close, but not quite. 
  
 Answer:            5 
 Correct:    Yes. 
 Why:            length() is a built-in prototyped as sub length($), 
             and a scalar prototype silently changes aggregates into 
             radically different forms.        The scalar sense of a ha\ 
 sh is 
             false (0) if it's empty, otherwise it's a string represent\ 
 ing 
             the fullness of the 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. 
  
 Answer:            37 
 Correct:    No. 
 Why:            `length %HASH' is nothing at all like `scalar keys %HA\ 
 SH', 
             which is a good bit more useful, in general. 
 Answer:            74 
 Correct:    No. 
 Why:            `length %HASH' is nothing at all like the size of the  
             list of all the keys and values in %HASH. 
  
 ======================================================================\ 
 == 
  
 Question:   If EXPR is an arbitrary expression, what is the  
             difference between $Foo::{EXPR} and *{"Foo::".EXPR} 
 Type:            Namespaces, Typeglobs 
 Difficulty: 6/7 
 Answer:            The first can create new globs dynamically, but 
             the second cannot. 
 Correct:    No. 
 Why:            Although you can get package Foo's symbol table via 
             the hash %Foo::, 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. 
  
 Answer:            The second is disallowed under `use strict "refs"'. 
 Correct:    Yes. 
 Why:            Dereferencing a string with *{"STR"} is disallowed 
             under the refs stricture, although *{STR} would not 
             be.  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 particular dynamic fashion. 
  
 Answer:            The first only happens at runtime, the second at on\ 
 ly compile time. 
 Correct:    No. 
 Why:            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. 
 Answer:            One is just a regular hash, the other a typeglob ac\ 
 cess 
             for a strangely named variable. 
 Correct:    No. 
 Why:            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. 
 ======================================================================\ 
 == 
 Question:   When would `local $_' in a function ruin your day? 
 Type:            Regular Expressions, Scoping 
 Difficulty: 6/7 (Hard) 
 Answer:            When your caller was in the middle for a foreach(@a\ 
 ) loop. 
 Correct:    No. 
 Why:            This looks close to the bizarre phenomenon known as  
             variable suicide, but as of this writing, you should be 
             safe from it. 
 Answer:            When your caller was in the middle for a while(<\ 
 >) loop. 
 Correct:    No. 
 Why:            However, if you do a `while(<>)' and forget to f\ 
 irst 
             localize $_, you'll hurt someone above you.  That's 
             because even though foreach() implicitly localizes 
             $_, a while(<>) does not. 
  
 Answer:            When your caller was in the middle for a while(m//g\ 
 ) loop  
 Correct:    Yes. 
 Why:            The /g state on a global variable is not protected by 
             running local on it.  That'll teach you to stop using 
             locals.  Too bad $_ can't be the target of a my() -- yet. 
  
 Answer:            When $_ was imported from another module. 
 Correct:    No. 
 Why:            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::_'.   
 ======================================================================\ 
 == 
 Question:   How do you match one letter in the current locale? 
 Type:            Regular Expressions 
 Difficulty: 4/7 (Medium) 
 Answer:            /[a-zA-Z]/ 
 Correct:    No. 
 Why:            You forgot the locale-specific letters. 
 Answer:            /[a-z]/i 
 Correct:    No. 
 Why:            You still forgot the locale-specific letters.  The /i 
             flag doesn't bring them in. 
  
 Answer:            /[^\W_\d]/ 
 Correct:    Yes. 
 Why:            We don't have full POSIX regexps, so you can't get at 
             the isalpha() <ctype.h> macro save indirectly.  You \ 
 ask 
             for one byte which is neither a non-alphanumunder, nor  
             an under, nor a numeric.  That leaves just the alphas, 
             which is what you want. 
  
 Answer:            /[:isalpha:]/ 
 Correct:    No. 
 Why:            Lamentably, this reasonably standard syntax is not 
             yet supported in Perl. 

Issue_08_Quiz
2. More Samples on Quiz

  • Issue_08_Quiz

                                                                                                                                   

Hipocrisy of the finest: "I agree that no single company can create all the hardware and software. Openness is central because it's the foundation of choice."
-- Steve Balmer (Microsoft) blaming Apple regarding iPhone, February 18, 2009

Last update 1999/02/20

All Rights Reserved - (C) 1997 - 2009 by The Labs.Com

Top of Page

The Labs.Com