Well, Per brian d foy's blog post, I'd like to answer the question "Why I'm Passionate About Perl". First of all, I should note my "The Joy of Perl" essay, which I wrote back in 2004. It gave a lot of good reasons why I like Perl so much and am still passionate about it. But now to answer brian's questions:
The person who introduced me to Perl showed me that... - I still remember him (Ran) telling me that one can write a TCP/IP client in 4 lines, and a TCP/IP server in 10 lines. (Or something like that). I ended up not understanding what regular expressions were all about and he explained that they matched patterns in texts. Back then, I had to learn perl 5 from perl*.pod (what are now the perldocs).
I first started using Perl to... - had to learn Perl (and Unix) because I wanted the job working for Ran's company. I liked both Perl and Unix so much that I understood why I had not been content with all the technologies I encountered previously. (DOS and Windows 3.11).
I kept using Perl because... that was what I knew and I was comfortable writing it, and found that most various techniques were readily available in some form or another. For example, after reading SICP I was able to easily implement the closure-based techniques shown there in Perl. Then after I learned Object-Oriented Programming in Perl, I found out how nice it was, and how much better it was than C++. (Which if you ask me now supports Object-Oriented Programming roughly as much as COBOL supports Functional Programming.)
I later on learned how to effectively use the CPAN, use accessors, and many other tricks and techniques. I got involved in the Local and International Perl community, which was also a lot of fun.
I'm not a Perl fanatic and see myself sometimes using, learning or experimenting with other technologies. But I still like Perl 5 the most.
I can't stop thinking about Perl... - actually I often can. The amount of time I spend coding is small, and Perl is even less than that.
I get other people to use Perl by quietly telling them how Perl is important and how it is enlightening and useful, and also telling them about the things I'm doing with Perl.
I also program in Bash, C/C++, PHP and a little Python (and small experimental stuff in many other languages) but I like Perl better since: 1. It's a real, and safe programming language unlike Bash. 2. It's much more easier to write than C, C++ or Bash. 3. It's more comfortable to me than Python due to the TMTOWTDY, use strict and other factors. (Though I can understand why Python has its appeal to some people.) 4. It's much less hacky than Bash and PHP. 5. The Perl community is great, and has a very healthy attitude.
Note that I'm still using bash for the command line and for some really minimal scripts, and am happy with it, and prefer it over Perl.
Comments are welcome. (I leave the comments open, as I almost always do).
Dear Lazyweb,
I'm looking for a recommendation for a good personal blog engine that I'd install on my site. It should be Free Software (preferably GPL-compatible); it should be Perl, Python or PHP (Perl is preferable), possibly also Ruby; it should be able to use PostgreSQL as a backend; and it should be good: easy to install, mostly works out of the box, easy to extend, with an active developer community, readable (not necessarily too modular) code, good security practices, etc.
Here's what I tried so far:
MovableType - has a weirdo HTML caching system, and ended up putting a lot of world-writable files on my hard disk. Also doesn't work out of the box with recent PostgreSQL's (which is easy to fix).
WordPress - from using it elsewhere I had at least three occassions where it ate my comments and refused to allow me to repost them. Also, it has many bad defaults like non-threaded comments, A single "Submit" button with no preview, no pure-HTML input, and these weird ?id=$INDEX URLs which I hate. All of them can be fixed using Plugins, but it's still an extra hassle.
It also had a very poor security record, and pkrumins said he isn't content with it for his blog, and working on something from scratch.
There are many other blog engines out there, but I'm looking for a personal recommendation from experience. Comment below or drop me a line. I'll probably blog here about what my final verdict is.
I wrote a new Essay about what makes software applications high-quality, as well as which parameters and methods, while desirable and quality-enhancing, are not exactly quality. It was inspired by a post on a public mailing list I set up, and Perl and perl 5 are mentioned there a few times, as are many other open-source projects.
It is available in several formats: HTML to read online (on Page), DocBook/XML source (which can in turn render other formats), PDF (please don't print it even though you are legally allowed to). The licence is CC-by-2.5. Comments are welcome.
OK, as I expected my previous entry sparked an active discussion - nothing like a good licences war to liven things up. But it was more civil than I expected. Here's a much more technical entry.
As I discovered, Test-Run-0.0115 consistently failed to pass "./Build test" on all BSD systems, while doing mostly fine on Linux. Inspecting the logs of the failure yielded a "File name too long" error. What happened was that I created a filename that was artificially very long (../t/../t/../t/), but still well within the limits of my Linux system's 4096 bytes limit for file paths. However, as I discovered the POSIX standard defined a minimum of 256 bytes for maximal paths which is what BSD is supporting.
The reason I had this long path in the first place was to make sure long paths are handled properly by the harness output after some customisations. This in turn was inspired by a problem I found when using Test-Run at my workplace for some internal test suite, which inspired me to write the Trim-displayed-Filenames plugin.
So after I received all these failure reports, I added some logic to t/output.t that makes use of POSIX::PATH_MAX() to keep the path at bay. A bit convulted, but it now passes on BSD systems (as well as Linux and Solaris), with a two isolated failures on Linux, which I have not looked into yet. I'd like to thank apeiron from Freenode for testing the pre-release in Mac OS X and verifying it works there.
In any case, I'm a bit tired of doing unknowledgable UNIX programming, and therefore would like to read the 2nd edition of Stevens' book (which is considered the Bible of UNIX programming). The book is kinda costy, and big (960 pages), so I think I'll renew my Safari subscription and see if I can read it there effectively. If I can't I'll just use it for something else, and order a paper-copy of the book.
And finally, I wonder how a 256-octets path limit can ever be enough. In this day and age of long filenames and UTF-8 ones (which require several bytes), one can expect that a path with a few especially long components will quickly overflow such a short limit. Can any BSD users comment?
This entry was adapted from some comments I wrote for a different, mostly orthogonal, journal post. I hope it's not too flamebait. If you have something to say, please try to be civil and good-natured. Here goes nothing:
Most modules on CPAN carry a licensing blurb saying something like "you can distribute this software under the same terms as Perl itself". This obviously begs the question what does it mean. Here is what it means for different Perl versions:
Early versions of perl, before it adopted the GPL were under a very restrictive loosely-defined licence.
After a while perl adopted the GPL exclusively.
Eventually, seeing that some people and companies had problems with the GPL, Larry Wall phrased the so-called "Artistic License", which was supposed to be more permissive than the GPL, but purposely phrased vaguley, and as such was found to be non-free and ergo GPL-incompatible.
In any case, the perl implementation was dual-licensed under the "Artistic License" (version unspecified) and the GPL version 2 or any later version. perl5 is still licensed under these terms.
For Parrot and for future work on Perl 6, the Artistic License 2.0 was created based on the original Artistic License. This license has been approved as a free software licence by the Free Software Foundation and found to be compatible with the GPL version 2 or Later. Parrot now carries this licence.
There's also the Clarified Artistic License which is an earlier effort to correct the original Artistic License and is the minimal set of changes to make it FSF-free and GPL-compatible. I suppose that now the Artistic License 2.0 would be preferable.
The problem is that perl up to and including perl-5.10.0 and bleadperl (which were licensed under the GPL version 2 or above but only the "Artistic License" not the "Artistic License version 1.0 or above". I've already noted that the Artistic License is problematic, but the GPL has its own share of potential problems (see also its FAQ), and is otherwise widely mis-understood, over-hyped (both positively and negatively) and disputed. For example, unlike the Artistic License, it does not allow (at least by linking or normal function calls) non-GPL-compatible code, including all non-open-source code, to make use of it.
Now, since both the "GPL version 2 or above" and the original "Artistic License" are problematic, and the term "under the same terms as Perl" may probably mean just that if it's a perl5 module (although who knows what it would means if someone would ever write a compatible Perl 5 implementation under a different software licence), then licensing a module as such is probably no longer such a good idea. There are several alternatives:
So my suggestion is that you use one of these licensing phrasings for your future work, and to re-license your old CPAN or Perl work (copyright ownership permitting) under such phrasings. It remains to be seen what will happen with perl5 itself which has 905 authors as of perl-5.10.0 many bringing in their own ownerships of the code. The Linux kernel now faces a similar problem if it would wish to adopt a different licence than the GPL version 2 (and no later version).
I suppose you can still make most use of perl5-like licensed code, in your own open-source, proprietary or in-house code, without getting sued, so I wouldn't worry too much. But it would still be a good idea to convert newer code (and code that can be easily converted) to licensing terms that are less ambigious, more usable, and that would play better with future versions of Perl.
For the record, most of my Perl and non-Perl open-source code is either Public Domain or MIT X11-licensed (which are both extremely permissive and allow sub-licensing), or if it is derived from a different code, then under the same licensing terms, but while disclaiming my explicit or implicit ownership (to allow the originator to relicense future versions of the code). The latter policy applies to my (relatively limited) contributions to perl5 where I am listed in the AUTHORS file.
This is cross-posted here from Israel.pm where I have yet to receive an answer.
I'm trying to process the directory components of a path (as an array) so that:
If the processing is to keep only the directories after "long-dir" then:
UNIX :/hello/there/long-dir/another/myfile.txt ==> another/myfile.txt
DOS : C:\Hello\There\Long-Dir\Another\myfile.txt ==> another\myfile.txt
UNIX:./hi/long-dir/another/myfile.txt ==> another/myfile.txt
DOS:.\hi\long-dir\another\myfile.txt ==> another\myfile.txt
To do this I turned to File::Spec and File::Basename and wrote the following code which seems insanely complicated. I marked the place where I do the actual processing using a callback:
use File::Spec;
use File::Basename;
sub _process_filename_dirs
{
my ($self, $fn, $callback) = @_;
my $basename = basename($fn);
my $dirpath = dirname($fn);
my ($volume, $directories, $filename) = File::Spec->splitpath($dirpath,
1);
# The actual manipulation.
my $dirs = $callback->([File::Spec->splitdir($directories)]);
my $final_dir =
File::Spec->catpath(
$volume, File::Spec->catdir(@$dirs), $filename
);
if ($final_dir eq "")
{
return $basename;
}
else
{
return File::Spec->catfile(
$final_dir, $basename
);
}
}
And so far I checked it works only on UNIXes (Linux in my case) and on relative paths.
So my questions are:
I should note that this hairiness is not limited to Perl. Common Lisp has a built-in portable path-manipulation abstraction that's also relatively complicated. See the "File and File I/O Chapter" and the a Portable Pathname library chapter
Recently I've encountered a modularity issue in my code, I had a function like the following
sub _is_event_pass
{
return ($self->_event->is_ok() ||
$self->_event->is_skip() ||
$self->_event->is_todo()
);
}
As you can see all I'm doing is calling methods on the _event. The right thing to do would have been to move it as method to the class of the _event() that will then use the object's instance itself. Now the problem is that the _event() field can be any of the TAP::Result:: hierarchy of classes
And it wouldn't be a good idea to sub-class and re-bless all of them.
So what to do?
What I eventually did is create an EventWrapper class, that has a field which is the actual object. Then I'm delegating all the methods of the TAP::Result classes that I use to that field. I.e:
sub is_ok
{
my $self = shift;
return $self->_tp_result()->is_ok();
}
sub is_todo
{
my $self = shift;
return $self->_tp_result()->is_todo();
}
(only I'm auto-generating these methods of-course).
And then I defined the is_pass function there like this:
sub is_pass
{
my $self = shift;
return ($self->is_ok() || $self->is_todo() || $self->is_skip());
}
Which works because these methods are delegated.
So
Of course, I made a good use of the fact that Perl is dynamically-typed and evaluates methods at run-time. If I wanted to do the same in strongly-typed OO languages, then I would have needed to figure out a way to delegate to all the methods of the various different classes in the hiearachy. Perhaps using run-time classes.
The Israeli Perl Mongers will hold their first meeting for this year on Sunday, 16 March, 2008at 18:30, in Screiber 008 in Tel Aviv University.
The meeting agenda is not final, but includes a presentation by Ran Eilam on "Config::* - The Alenby St. of CPAN", and a fallback "There are too many ways to do it" presentation.
As a continuation to my previous entry about IO-Socket-INET6, I'd like to note that I received several responses to my message about resuming its maintenance. Eventually, the original author replied too and agreed to give me a co-maintainer status on PAUSE.
So I wrapped things up and uploaded a new version of IO-Socket-INET6 to the CPAN, and it indeed got indexed properly. I already received several error reports from CPAN testers, but I'm not sure I can do anything about them, because the end-hosts don't seem to support IPv6 well.
Next I'd like to increase the module's kwalitee and to look at bug reports.
Now I can be proud that there's now a small part of me in SpamAssassin.
After I udpated my Mandriva Cooker system a few days ago (after the perl package there had been upgraded to 5.10.0), I noticed that SpamAssassin's "spamd" and "spamassassin" started generating the following warnings:
Constant subroutine IO::Socket::INET6::AF_INET6 redefined at
/usr/lib/perl5/5.10.0/Exporter.pm line 66.
at/usr/lib/perl5/vendor_perl/5.8.8/IO/Socket/INET6.pm line 16
Prototype mismatch: sub IO::Socket::INET6::AF_INET6 () vs none at
/usr/lib/perl5/5.10.0/Exporter.pm line 66.
at/usr/lib/perl5/vendor_perl/5.8.8/IO/Socket/INET6.pm line 16
Constant subroutine IO::Socket::INET6::PF_INET6 redefined at
/usr/lib/perl5/5.10.0/Exporter.pm line 66.
at/usr/lib/perl5/vendor_perl/5.8.8/IO/Socket/INET6.pm line 16
Prototype mismatch: sub IO::Socket::INET6::PF_INET6 () vs none at
/usr/lib/perl5/5.10.0/Exporter.pm line 66.
at/usr/lib/perl5/vendor_perl/5.8.8/IO/Socket/INET6.pm line 16
After investigating, I found out that there was a "use Socket6;" call there, which imported the AF_INET6 and PF_INET6 symbols, which were already imported into the IO::Socket::INET6 package by previous Socket and IO::Socket calls.
In order to get rid of the warnings, I eventually decided to only selectively import symbols from Socket6, and imported the necessary symbols minus AF_INET6 and PF_INET6. In order to get IO::Socket::INET6 to pass its tests, I had to fix its tests, which had been broken before any modifications to it started. LeoNerd helped me with that, so thanks! Then I submitted a modified SRPM to Mandriva with a patch and went to sleep happy.
Today, when I woke up and checked my email, I was surprised to discover that about 20 spam mails landed at my inbox. As it turned out, they didn't have the SpamAssassin headers. Running spamc from the command line, yielded an unmodified message, while the standalone spamassassin program worked perfectly. So I started to investigate why spamc and spamd failed.
I ran into some trouble trying to point spamd to a modified IO::Socket::INET6 module, because it was tainted, and won't read the PERL5LIB environment variable (it's documented in perlrun. I had to modify the sources and use "use lib".
I also had a lot of trouble trying to see why IO::Socket::INET6 fails and where. This eventually was resolved by running spamd like this:
perl -T blib/script/spamd -c -m5 -H --syslog="stderr info"
Then I could see the error clearly. Apparently I missed importing inet_ntop() from the Socket6 module, which was called by some functions that were not ran in the unit tests, and so it was only detected when spamd ran. This is one disadvantage of dynamic, symbolic languages such as Perl, and can be prevented in statically compiled languages such as C and as far as I know, Java as well.
Well, but since the code in question was Perl, I just added tests for the functions calling inet_ntop() and added it to the imports. After installing the modified module, spamd worked again, and I submitted a new patch for inclusion into Mandriva. So the enhancements now are that the warnings have been removed, the tests passing and the test suite made more robust.
As these modifications, may be useful for other platforms besides Mandriva, I sent a message to the maintainer and other designated parties regarding resuming the maintenance of IO::Socket::INET6.
Some other lessons from this:
Right now I'm cranky and happy at the same time, because I've spent half-a-day on this bug.