I had an idea, and as I worked on it, two forms emerged.

Blessed Objects:

$"='|';$|=$d=1;@b=map{bless{t,"$_ ",r,$d*=-1}}qw/Just another Perl hacker,/;sub v{$s=shift;my$_=$$s{t};$r=int y===c*$$s{a}/360;$$s{a}= ($$s{a}+$$s{r})%360;s%(.{$r})(.*)%$2$1%;$_}{print"\r@{[map{v$_}@b] }";select$x,$y,$z,2e-3;redo}

This section doesn't contain spoilers per se, but a discussion of how it evolved.

It should come as no surprise as you look it over that it started out as a relatively clean implementation of a class that gets instantiated into several blessed objects. There were the usual accessors and the usual call to a subroutine designated as a constructor.

Little by little I found chunks that could be removed, condensed, written a more obscure way, and so on. In some cases member functions that were used only once got inlined into a single member function. Then the constructor got pulled out of the customary function and into a loop's block. In the end, I got 228 keystrokes (231 if you count newlines, which are significant), and something pretty funky.

If I had stopped there, all I would have posted would be the preceding code and a little wisecrack or something.

But then I started thinking about the fact that with Perl, functions can be used as first class objects themselves thanks to closures and subrefs. (Obviously this isn't a new discovery, but it's sometimes overlooked.) This seemed like a perfect example of where that sort of approach could work out nicely. That idea led to a second quest, and here's how it turned out."

Functional Objects:

$"='|';$|=$d=1;@b=map{my($t,$h,$a)=("$_ ",$d*=-1);sub{my$_=$t;$r=int y===c*$a/360;$a=($a+$h)%360;s%(.{$r})(.*)%$2$1%;$_}}qw/Just another Perl hacker,/;{print"\r@{[map{&$_}@b]}";select$x,$y,$z,2e-3;redo}

What I found interesting though not surprising is this: While in its fully deobfuscated version the classical Blessed Object Oriented form was the easiest to develop and grasp. But as the code got reduced to the bare minimum needed to retain functionality, the Functional approach became so elegant that even its obfuscated and golfed version still feels pretty and intuitive to me. I'm sure beauty is in the eye of the beholder. But I guess it kind of took me by surprise that the more I streamlined and condensed the code in the classical Object Oriented version, the uglier it became, while the more I streamlined and condensed the code in the Functional version (or functions as objects), the more it began to shine as the elegant solution. And as a bonus to myself, I even got it down to 201 keystrokes (203 if you count newlines, which are significant).

Of course traditional OO has a lot of well-developed features that aren't needed for a simple gadget like this. Functional programming with Perl doesn't provide (from what I know) for concepts like inheritance (which may be a positive, depending on who you ask). But it is a paradigm with a lot of merit for simplifying code through generalization and abstraction. Anyway, this was just a fun little pursuit; I hope you like it.

The extra discussion may be unconventional for this sort of post, but I just enjoyed the process and felt like sharing a little about it.

Enjoy!


Dave

Replies are listed 'Best First'.
Re: Objects: Classical and Functional
by ambrus (Abbot) on Oct 25, 2011 at 09:42 UTC
Re: Objects: Classical and Functional
by ambrus (Abbot) on Oct 25, 2011 at 18:45 UTC

    Here's another variant. (This works only on perl 5.14 or newer.)

    $_="\rH48lpt|nFfb^62RN|1eQ=qu|KkC?;[WwO"; select$,,q,,,q$$,3/y$4-w0-3$0-w$while$|=print y(0-{) "JPr,ueersrhetltk oc naJPahue sr tlr, er heJPtkueocsrnatlah "r