Archive for October, 2006
Tuesday, October 31st, 2006
sub get_proto { return $protocol; } sub set_proto { $protocol = shift; } } # End of block containing closures print get_proto(); (We’ve removed anything not necessary to understanding this point.) If you run this, you’ll see that it indeed knows what the default protocol is, and you’ve successfully isolated that shared variable to the two subroutines that use it. Let’s say that later you decide that the subroutines are better off declared at the end of the file so that you can start reading with your main program Perl can handle forward references, right? So you change it to print get_proto(); { my $protocol = “ftp”; # default sub get_proto { return $protocol; } sub set_proto { $protocol = shift; } } # End of block containing closures But now when you run the program, get_proto will complain about an uninitialized variable. The reason is closely related to our previous error: when we call get_protoin the first line, $protocol hasn’t been initialized because we haven’t gotten to the line where that happens yet. The reason there’s no complaint from strict about it being an undeclared variable in the closures is that it has been declared; however, that happened at compile time, and the assignment of the default value won’t happen until run time. You can avoid this problem naturally by following Perl of Wisdom #18. If you don’t yet understand closures but you’re intrigued, read “What’s a closure?” in the core Perl documentation section perlfaq7. Chapter 11. Resource Failure “He’s dead, Jim.”
Hint: If you are looking for very good and affordable webspace to host and run your j2ee hosting application check Virtualwebstudio j2ee web hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
You have a subroutine that should set a private variable based on some condition. Not unreasonably, you might code something following this general form: sub ordinal { my $what = shift; my $res = ‘first’ if $what == 1; $res = ’second’ if $what == 2; return $res; } But you’d be wrong. If we run this through perl-lwith for(1..3){ print ordinal($_)}, we get the result: first second second Eh? Shouldn’t that last line be a warning about an undefined value? Regrettably, you’ve fallen afoul of an internal optimization in Perl[4] that keeps the storage assigned to lexical variables around after they’re gone, on the premise that they may be needed again shortly. The my statement has both a compile-time effect (declaring the variable) and a run-time effect (setting it to undef, unless the statement is qualified by a failed condition). [4] That may change in a future version. Never qualify a my statement with a condition. Note that this is not talking about putting my statements inside conditions: if ((my $tag = $element->tag) ne ‘p’) { # Code using $tag } while (my ($key, $value) = each %hash) { … } which is a very good idiom in that it concisely limits the scope of the new variable to precisely the block in which you need it. 10.6 Bringing Some Closure Understanding how lexical variables work is worth the effort. Suppose you have advanced to the stage of understanding closures give yourself a pat on the back and you decide to code a few subroutines that use a private variable that way: { my $protocol = “ftp”; # default
Hint: If you are looking for very good and affordable webspace to host and run your j2ee hosting application check Virtualwebstudio j2ee web hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
my %port = (http => 80, https => 443, ftp => 79, nntp => 119, gopher => 70); while () { if (my ($url) = m#((w+)://S+[w])#) { $url = ~ s#:$port{$2}/#/# if $port{$2}; print “URL found: $urln”; } } (Yes, there are better ways of isolating URLs from text; this code doesn’t even find more than one per line. But that’s not the point we’re about to make.) Flushed with the cleverness of our code, we feed it the input: The President (http://www.whitehouse.gov:80/president/) said today that he liked ferrets (http://www.ferretcentral.org/), and was considering placing a picture of one (ftp://ftp.optics. rochester.edu:79/pub/pgreene/icons/central-logo-t.gif) on the next version of the national flag; but he thought they were too often confused with gophers (gopher://gopher.tc.umn.edu:70/11/). expecting to see the output:[3] [3] We indented continuation lines in the input and output to make them easier to read. URL found: http://www.whitehouse.gov/president/ URL found: http://www.ferretcentral.org URL found: ftp://ftp.optics.rochester.edu/pub/pgreene/ icons/central-logo-t.gif URL found: gopher://gopher.tc.umn.edu/11 But instead, we see: URL found: 4294967294 URL found: 4294967295 URL found: 4294967294 URL found: 4294967294 If you run this program through Deparse, you’ll see the line $url = ~s[:$port{$2}/][/] if $port{$2}; which gives us just enough of a clue if we haven’t found the typo already. The space we accidentally put inside the regex binding operator has changed its meaning to “$urlis
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
assigned the one’s complement of the result of this substitution on $_ (which in a scalar context is the number of substitutions made).” 10.3.1 Flashback Remember in Chapter 8 we wondered why Perl placed the error with the transposed for clauses on the wrong line? Now we know how to find out! $ perl -MO=Deparse temp.pl Useless use of numeric lt (<) in void context at temp.pl line 13. my $fmt = '%10s ' x 5; printf "$fmtn", qw(Kelvin Celsius Rankine Fahrenheit Reaumur); $fmt = '%10.2f ' x 5; my $kelvin = 0; while ($kelvin += 10) { my $celsius = $kelvin - 273.15; my $rankine = $kelvin * 9 / 5; my $fahrenheit = $rankine - 459.67; my $reaumur = $celsius * 4 / 5; printf "$fmtn", $kelvin, $celsius, $rankine, $fahrenheit, $reaumur; } continue { $kelvin < 500 } Well, look at that. The dirty truth about for loops emerges: they're nothing but while loops in fancy clothes. The test clause got relocated to a continue block, where, of course, it makes no sense, being an expression in void context. 10.4 printf Formats Don't Impose Context If you're a die-hard C programmer (and is there any other kind?), you might think that to print the number of entries in an array, since the %dprintfformat specifier means "number," well gosh, a number is a scalar, and so that's the context it'll put its argument into: printf "Number of entries in @foo = %d", @foo; but by now you know us too well to fall for that yes, @foo is in list context here, because that's what printf is prototyped to take. So you'll either get the first entry of @fooprinted, or a complaint if that's not a number. 10.5 Conditional my
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
The specification of that function says that if $filedoesn’t exist, stat returns undef, which certainly isn’t an object. Therefore $filedoesn’t exist. And the reason it doesn’t exist is because $file doesn’t contain an absolute path and therefore is interpreted relative to the current directory. The current directory won’t contain files with the same names as the ones we read with readdir except by coincidence and except for the two files that every directory contains (. and ..). This is why we get some initial output that makes it look as though the script is working. It isn’t; it’s reporting the times for different . and .. from the ones we wanted. The fix is easy: just qualify $filewith $dir: use strict; use File::stat; my $dir = shift || ‘.’; opendir DIR, $dir or die “Error opening directory $dir: $!n”; while (defined (my $file = readdir DIR)) { print “File $file was last modified on ” . localtime(stat(”$dir/$file”)->mtime), “n”; } closedir DIR; [1] This works even if $diris relative or contains ../. [1] Using / as a directory separator works on Unix and Windows (Perl turns it into a on the latter). A truly operating system-independent way of forming the path would use File::Specand replace “$dir/$file” with File::Spec->catfile($dir, $file); 10.3 But What Did It Mean? The following program is designed to reprint its input lines prefixed with an increasing date that skips weekends: #!/usr/bin/perl -w use strict; use Time::Local; my $t = timelocal(0,0,0,31,11,99); # Dec 31 1999 while (<>) { my ($m, $d, $y) = (localtime $t)[4,3,5]; $y %= 100; $m++; print “$m/$d/$y $_”; dp { $t += 86400 } while (localtime $t)[6] == 0 || (localtime $t)[6] == 6; } However, the output shows a date that doesn’t change:
Hint: This post is supported by Gama besplatan domen provider
Posted in perl | No Comments »
Tuesday, October 31st, 2006
12/31/99 This is the first line 12/31/99 This is the second line 12/31/99 This is the third line Running under the debugger won’t reveal anything other than the fact that $t isn’t being increased in the do block. Wait a minute. It doesn’t say do, does it? It’s a typo: dp. Yes, we could fix the program right now. But curiosity demands that we wonder why Perl has no objections! What could it be thinking we mean? Enter the B::Deparsemodule. The B stands for “back-end,” which is to say, this module accepts input from the Perl compiler after it has created a binary opcode tree from a program. The whole purpose in life of B::Deparse is to turn that opcode tree back into Perl. For instance, you can use it to turn a subroutine reference into program text in the middle of a program. Deparseisn’t quite perfect you may see some odd output, at times even incorrect output but it’s getting there.[2] Let’s see what we get when we run it on just a part of the line of code that’s bugging us. Notice that we don’t invoke it with a use statement but rather with a funny variant of the -Moption designed for back-end modules: [2] Larry Wall said that Perl 5 should be translatable into Perl 6 via a kind of Deparse module, so we can expect considerable progress. % perl -MO=Deparse -e ‘dp { $t += 86400 } while (localtime $t)[6] == 0′ do { $t += 86400 }->dp while (localtime $t)[6] == 0; -e syntax OK Aha! Perl is interpreting our typo as a use of the indirect object method syntax it thinks we want to call the dpmethod of whatever the block $t += 86400 evaluates to. So this is no longer a doBLOCKwhileEXPRESSION construct (which guarantees the block will be executed at least once). Instead it is a STATEMENTwhileEXPRESSIONconstruct (where the statement is do { $t += 86400 }->dp), which means that the statement will be executed only if the expression is true, which in this case, it isn’t to begin with. The Deparsemodule can often explain how perl is parsing your code. Note: Deparse only came into the core with version 5.005, and it’s documentation has some additional options worth checking out, like the ability to totally parenthesize expressions so you can see how precedence is determined. (And if you see ‘???’in the output, that stands for a constant in the input that was optimized by perl to the point where its value was not available to Deparse.) Here’s another example in which Deparse helps. Let’s say you’re scanning text to pull out URLs and want to clean them up a little by removing redundant default port numbers:
Hint: This post is supported by Gama besplatan domen provider
Posted in perl | No Comments »
Tuesday, October 31st, 2006
An even better choice would be the oroperator introduced in Perl 5, which has such low precedence that you can leave out the parentheses on open: open FH, $file or die “Error opening $file: $!n”; 10.2 Reading Directories This has bitten us more times than we care to admit: readdir() returns the list of filenames in the directory, but they are not qualified by the directory itself. Consider the following program: use strict; use File::stat; my $dir = shift || ‘.’; opendir DIR, $dir or die “Error opening directory $dir: $!n”; while (defined (my $file = readdir DIR)) { print “File $file was last modified on ” . localtime(stat($file)->mtime), “n”; } closedir DIR; It takes a directory as its argument, defaulting to the current directory. This program prints out the names and modification times of all the files in the current directory. If run with no arguments, the program runs fine. If we then run it with an argument (this example is on Unix), it appears to start working and then fails: File . was last modified on Sun Mar 28 14:36:27 1999 File .. was last modified on Tue Aug 3 15:29:12 1999 Can’t call method “mtime” without a package or object reference at mod_times.pl line 9. What happened here? First, we see the error refers to line 9 and that perl attempted to invoke the mtimemethod on something that wasn’t even an object. What was the object? It was the result of the call to stat($file) (we’re using the stat routine from the File::stat module here, instead of the core perl stat routine that returns a list; it saves us from having to look up the index of the mtimeelement).
Note: If you are looking for top 10 and very good webhost to host and run your jsp application check Actions jsp hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
Semantical errors are a way of saying that when all else succeeds, you can still be wrong. The program compiles; it runs without any kind of run-time exception; it just doesn’t do what you intended. This is why you need system testing (see Chapter 6). (If you’re relatively new to Perl, this chapter might raise the hairs on the back of your neck a little. Feel free to return to it after you’ve gotten more comfortable with the language.) Here’s a tour of some examples of this obnoxious species of bug. 10.1 A Bit Illogical Perl has several ways of saying and and or: Table 10-1. And, Or, and Xor Operators in Perl Operation AND OR XOR bitwise (non-short-circuiting) & | ^ logical (high precedence) && || logical (low precedence) and or xor (There is no high-precedence logical XOR operator.) The consequences of picking an operator from the wrong row are usually annoying mistakes like open (FH, $file) | die “Error opening $file: $!n”; which dies whether or not the open succeeds, because the | operator is strictly a bitwise arithmetic or string operator, which evaluates both of its operands so that it can return the result of ORing their bits together. In this case, you want ||, which is a logical operator that evaluates its left-hand side and returns it if true; otherwise it evaluates and returns its right- hand side.
Note: If you are looking for top 10 and very good webhost to host and run your jsp application check Actions jsp hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
# Code to acquire a database connection atexit(&cleanup); # More database code which might fail } This ensures that no matter how that code block is exited, the cleanupsubroutine to break the connection gracefully will be run. 9.5 Confession Is Good for the Soul Sometimes your program dies not in your code but in some module you call suicide by association if you will. A module that wants to die is supposed to call Carp::croakinstead, because croakreports the location of death as the place the module function was called, not the line of code in the module function containing the croakcall. Some modules don’t do this. Either they call die, or they call another module that croaks; either way, you’re left with an error message that doesn’t tell you which line of your program caused its untimely demise. If this happens, here’s a quick way to force it to ‘fess up. Near the beginning of your program, insert the following: use Carp qw(cluck verbose); $SIG{__DIE__} = sub { confess @_ }; $SIG{__WARN__} = sub { cluck @_ }; Now whenever your program calls die/croakor carp/warnit ends up calling confessor cluck[9] instead, which have exactly the same effect except they print a stack trace of how they were called that goes all the way back to your main program. [9] Perl is nothing if not whimsical. Presumably in this case it helps to dispel the air of morbidity surrounding the whole topic of program death. Chapter 10. Semantical Errors “Pay attention even to trifles.” A Book of Five Rings, by Miyamoto Musashi
Note: If you are looking for top 10 and very good webhost to host and run your jsp application check Actions jsp hosting services
Posted in perl | No Comments »
Tuesday, October 31st, 2006
Bullet-proof your program by trapping exceptions and handling them gracefully. Let’s stop beating around the bush. What we really want is the ability to type exceptions and preferably also to subclass them, then catch them according to class while passing along instance-specific data.[8] Just like in Java. While we’re at it, it should use the same try … throw … catch syntax. [8] Not everyone thinks this way, just to be fair. If you’d rather stick with die… eval, you’ll be in plenty of company. It seems that the Perl mascot could just as well be a chameleon as a camel, since it can take on so many colors. An implementation of the try … throw … catch capability is in the module Error.pm by Graham Barr, on CPAN (http://search.cpan.org/search?dist=Error). It allows you to write things like try { # Some relational database-munging code. Somewhere # inside this something might raise an exception with # a line like: throw Exception::SQL (-text => ‘Bad SELECT statement’); } catch Exception::SQL with { # Code to handle SQL exceptions } catch Exception::IO with { # Code to handle I/O exceptions } otherwise { # Code to handle other kinds of exceptions }; Exception::SQLand Exception::IO are classes of exception that we created earlier by the simple expediency of inheriting from Error itself: @Exception::SQL::ISA = ‘Error’; @Exception::IO::ISA = ‘Error’; An alternative to Error.pm is Brad Appleton’s AtExit CPAN module (http://search.cpan.org/search?dist=AtExit), which allows you to specify a handler routine to be executed whenever the current scope is left for any reason, similar to the C++ auto_ptr template class. For instance: use AtExit; … {
Note: If you are looking for top 10 and very good webhost to host and run your jsp application check Actions jsp hosting services
Posted in perl | No Comments »