Patrick (patrickwonders) wrote,
Patrick
patrickwonders

  • Mood:

There is too much Perl in Perl.

Perl has a reputation for looking like line noise. Of course, one can write Perl that's moderately readable. But, Perl has a much deeper relationship with line noise than just the superficial appearance.

If you take a heap of line noise and drop one character, is it still line noise? Yes (unless you had only one character in the heap, then things get a little zen about whether no noise is line noise). If you take a heap of Perl and drop one character, is it still Perl? Very likely (even if you only had one character in the heap).

Here are two lines of totally valid Perl. One was what I had intended to type. The other is what I did type.

@names = ( map { $_->{'name'} } @records );
@names = ( map { $->{'name'} } @records );

So, what I had intended to do was fish out the name from each hash in the records array. Instead, what I did do was: for each hash in the records, totally ignore it in favor of storing whether the number of lines left on the page is bigger than the address of an anonymous hash that contains one key with an undef value.

Questions:

  • Who here has ever used $- (intentionally)?
  • Who here would have used $- had they known it existed?
  • Why can I make a hash with a key but no value (without at least some warning)?
  • Why can I compare a number and a hash reference (without at least some warning)?

Bonus points: if scalar {'name'} would return HASH(0x800168), then the comparison is false unless $- is greater than 0x800168.

Now, lest you think my comparison with line noise is not wholly satisfied with this one example. Let's look at that line again. I am first going to show the line. Then, I am going to show the same line with a dot (.) in place of any character that I could delete from the line and still have legitimate strict Perl. Then, I am going to show the same line with a dot (.) in place of any character that I could delete from the line and still have legitimate Perl.

@names = ( map { $_->{'name'} } @records );
@names.=.(.map.{.$...{'....'}.}.@records.);
@......=.(.map.{.$...{'....'}.}.@........);

Depending on the context, I could even nuke the semi-colon. So, of 43 characters, I could delete any of 16 of them (more than 37%) and still have Perl that's happy with use strict;. I could delete any of 28 of them (more than 65%) and still have executable Perl. The ratios would be slightly higher if I had used barewords. The ratios would be slightly lower if I had gotten rid of the whitespace or used shorter variable names.

Note: all three of these abominations are legal:

$->{'name'}
$_>{'name'}
$_-{'name'}

Some time back, I was talking about Perl's permissiveness to a non-programmer. He said, That must make it really tough to get something to compile. I said, On the contrary, almost anything you type compiles. It just does something different than you had intended it to do. Perl reminds me of this at least once a week.

Tags: perl, programming
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 3 comments