Here are some Kwikis for the Perl programming language.
Post your Kwikis below. Refactor as necessary.
Area Perl Mongers:
- A nice web calendar written in Perl. Very easy to install and use. Kwiki as applied to a web calendar.
A Perl solution to fixing a Sun Java JVM bug: PerlAndJavaBugId- 4635869
- When creating in-memory ZIP archives as strings with Archive::Zip and IO::Scalar,
- The Sun Java JVM prior to 1.4.2 will throw an exception:
- java.util.zip.ZipException: invalid EXT descriptor signature
Perl Kwikis
Klingon
- Question:
- Is there a Perl function that returns a list of all child PIDs for a given PID?
- Solution:
- See CPAN Module : Proc: : ProcessTable
- Question:
- How do I edit a file inplace from inside an running perl program?
- Solution:
- Chip Salzenberg provides an answer. See http://www.perlmonks.com/index.pl?node_id=128200
Little-known fact:
- The "-i" flag just sets the $^I variable.
- You can set it yourself.
- So set @ARGV, read <>, and print the result is all you have to do.
Thus:
local $^I = '.bak';
local @ARGV = ("$dir/$header_file");
while (<>) {
s/foo/bar/; # whatever you want
print;
}
Presto, magico, all done!
- Question:
- Subtracting one-dimensional arrays (lists). I have two equal-sized arrays with numbers. How can I subtract one from the other?
For example:
my @foo = (1, 2, 3, 4, 5);
my @bar = (5, 4, 3, 2, 1);
my @bat = @foo - @bar ; # (-4, -2, 0, 2, 4) -- doesn't work
I've written a for loop which pushes the difference:
for (my $i=0 ; $i <= $#foo ; $i++ ) {
push(@bat, $foo[$i] - $bar[$i] ) ;
}
But thought perl might have a more elegant method. Maybe map?
- Solution:
- Perhaps you could take a look at the Perl FAQ?
perldoc perlfaq4
or
http://www.perldoc.com/perl5.6/pod/perlfaq4.html#How-do-I-multiply-matrices-
Or, use the Math::Matrix or Math::MatrixReal modules (available from CPAN) or the PDL extension (also available from CPAN). See:
If your situation is truly this simple and all you need is a one-off, then yes, 'map' is the correct operator. You may want to read up on the schwartzian transform as well.
- Are your arrays always one-dimensional?
- Do both one-dimensional arrays always have the same magnitude?
- Do you require type-checking on what's passed to the subroutine?
sub diff{my($a,$b)=@_;return map{$$a[$_]-$$b[$_]}0..$#{$a}}
my @foo = (1, 2, 3, 4, 5);
my @bar = (5, 4, 3, 2, 1);
my @bat = diff(\@foo,\@bar);
If you use Math::Matrix, then you want to look at the 'subtract' method. Even though the docs refer to it as the typographically-challenged 'substract' method.
use Math::Matrix;
my $foo = new Math::Matrix (1, 2, 3, 4, 5);
my $bar = new Math::Matrix (5, 4, 3, 2, 1);
my $bat = $foo->subtract($bar);
And Perl 6 will have the ability to subtract vectors like so:
@answer = @foo ^- @bar;
And you can also iterate over multiple lists:
for @foo; @bar -> $f; $b { ... }
- Question:
- When is the U.S. Election Day for 2004?
- Solution:
- Try this Perl one-liner.
perl -MDate::Manip -e 'print UnixDate(ParseDate("1st tuesday in November 2004"), "%m/%d/%Y")'
- Question:
- When are the CWE-LUG meetings for 2004?
- Solution:
- Run the Perl program below.
#!/usr/bin/perl
use Date::Manip; # Obtained from CPAN
# Figure out when the rest of the CWE-LUG meetings are
@date = &ParseRecur("3rd sunday of every month in 2004");
$now = ParseDate("today"); @date = grep {$_ >= $now} @date;
print "CWE-LUG Meetings: ", map(Date::Manip::UnixDate($_,"%m/%d "), @date),"\n";
- Question:
- Am I affected by the Jan 19, 2038 Unix Epoch Bug?
- Solution:
- You can even see if your computer is affected with ...
TZ=GMT perl -MPOSIX -e '($e=($s=2**31)-=2)+=3;print ctime($s++)while$s<$e'
This 74 character gem, on a Solaris box, prints:
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:07 2038
Indicating my perl 5.8.0 on Solaris8 sparc is OK. Sun has decided that any values larger than this will return this maximum value. Since it is not possible to display a larger value, they simply display the largest possible value.
On a cygwin-on-Windows2000 environment, this prints:
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Fri Dec 13 20:45:52 1901
Indicating that perl 5.8.2 on cygwin 1.5.5(0.9432) has the bug.
- Question:
- What is the shortest way to display yesterday's date in YYYMMDD format?
- Solution:
- Eliminate the whitespace added for formatting from the one-liners below:
# Mike
perl -e '@ymd=(localtime(time-86400))[5,4,3];\
@ymd[0]+=1900;@ymd[1]++;\
printf("%04d%02d%02d\n",@ymd)'
# Ben Sharp
perl -e '$d.=sprintf("%02d",(localtime(time-86400))[$_])for 5,4,3;\
print $d+19000100,"\n"'
The 2nd place winners at 77 characters ( BillOdom):
# Bill Odom
perl -e"printf'%04d%02d%02d',(@d=localtime time-86400)[5]+1900,$d[4]+1,$d[3]"
perl -e"@ARGV=(localtime time-86400)[3..5];printf'%02d'x3,1900+pop,1+pop,pop"
The winner at 74 characters ( BillOdom with credit to BenSharp):
# Bill-en Sharp-Odom
perl -e"print 19000100+sprintf'%d%02d%02d',(localtime time-86400)[5,4,3]"
This can be shortened using the standard POSIX module, or the Date::Simple module from CPAN.
# Aaron Malone
perl -MPOSIX -e 'print strftime("%Y%m%d\n",localtime(time-86400))'
# Mike
perl -MDate::Simple -e 'print today->prev->format('%Y%m%d')'
And if you have the GNU or FreeBSD date utility, this can be done from the shell with:
date -d yesterday +%Y%m%d # GNU date, 25 chars
date -v-1d +%Y%m%d # FreeBSD date, 19 chars
FAQ Template (do not remove):
- Question:
- Solution: