Beautifying Perl
I totally fell in love with Ruby ever since I started using it more than a year ago. The language’s syntax and constructs are very, very elegant (with a few exceptions… I’m talking about you, StringIO.new.is_a?(IO) == false). The ‘do’ blocks are simply brilliant, they make working with closures a breeze and aesthetically pleasing. Ruby’s Array, Enumerable and Hash classes make heavy use of this.
Compared to Ruby’s syntax, Perl’s seems like something from the 80s. Perl is often the target of “my-code-is-more-unreadable-than-yours-but-I-can-do-it-in-fewer-lines” jokes. I can write readable and maintainable code, but no matter what I do, it’s still nowhere near Ruby’s level. All the referencing and dereferencing of arrrays and hashes makes things ugly. %, $ and @ everywhere, urgh. And working with collections takes more code than in Ruby. I can’t tell you how many times I had to write stuff like this:
-
my $foo_is_ok;
-
foreach my $value (@foo) {
-
if ($value satisfies some condition) {
-
$foo_is_ok = 1;
-
last;
-
}
-
}
-
if ($foo_is_ok) {
-
…
-
}
In Ruby I can just do:
-
if foo.any? { |x| …some expression involving x… }
-
…
-
end
There’s List::Util but they deliberately left out the ‘any’ function because it’s “easy to implement”. Urgh. -_-
I write a lot of text parsers in Perl. And each time I have to manually strip newlines from a read line with:
Seriously, why can’t I call ‘$foo->strip()’ or something like in Python or Ruby?
And print(). In 99% of the cases I want to print a newline as well, so I have to write print "$foo\n"; Why is there no puts()-like function that automatically prints the newline as well? It would save me a few keystrokes.
But no more. I’ve had enough. Enter the Peanuts library. Now you can write:
-
use Peanuts;
-
-
my $array = Array(["hello", "world", "foo", "bar"]);
-
puts $array
-
->map(sub{ $_ . "!" })
-
->findAll(sub{ /o/ })
-
->reject(sub{ /f/ })
-
->join(‘, ‘);
This would print “hello!, world!\n”.
Other Ruby-isms include:
-
use Peanuts;
-
-
my $s = String(" hello world ");
-
puts $s->strip(); # => "hello world"; This is actually a new String object.
-
puts $s->Strip(); # in-place version of strip()
-
-
my $h = Hash({ x => ‘y’ });
-
$h->merge({ foo => ‘bar’, a => ‘b’ });
-
$h->Merge({ baka => ‘baka’ }); # in-place version of merge()
-
-
-
package MyClass;
-
sub foo {}
-
Package()->aliasMethod(‘bar’, ‘foo’); # Now we have an alias! No ugly Perl symbol table messing syntax!
-
Package()->chainMethod(‘foo’, ‘trees’); # Like Rails’s alias_method_chain; now
-
# we have foo_with_trees() and foo_without_trees()
The source code is at this SVN repository:
http://public.railsplugins.net/repos/peanuts/trunk
It is licensed under the MIT license.
