← Back to context

Comment by KaiserPro

3 days ago

I took great pride in making readable, maintainable perl.

I worked at a VFX place that was held together by loads of perl, written over a good 15 years. Some of it was clever, but most of it was plain readable scripts.

The key to keeping it readable was decent code reviews and someone ripping the piss out of you for making unreadable soup.

Its all python nowadays, I do miss CPAN, but I don't miss perls halfarsed function args.

However for the longest time, the documentation for perl was >> than python. At the time python doc were written almost exclusively for people who knew how to python. Perl docs assumed you were in a hurry and needed an answer now, and if you were still reading by the end assumed you either cared or were lost and needed more info.

With the rise of datascience, python has lost its "oh you should be able to just guess, look how _logical_ the syntax is" to "do it like this."

I also found "perlcritic" to be very useful.

> perlcritic is a Perl source code analyzer. It is the executable front-end to the Perl::Critic engine, which attempts to identify awkward, hard to read, error-prone, or unconventional constructs in your code. Most of the rules are based on Damian Conway's book Perl Best Practices. However, perlcritic is not limited to enforcing PBP, and it will even support rules that contradict Conway. All rules can easily be configured or disabled to your liking.

https://metacpan.org/dist/Perl-Critic/view/bin/perlcritic

It helped me a lot. I think every Perl developers should use it, might help to avoid headache later on. Be careful with severity level "brutal" and "cruel" and "harsh", however. I think "gentle" works in many cases. That said, I used "brutal" and I only fixed the legitimate issues. "brutal" helped me write a proper POD, for one, as "gentle" does not complain about that.

> I took great pride in making readable, maintainable perl.

In the past when I used perl, I did the same thing.

But I came to learn one thing about perl - its good point is its bad point.

When I used it, perl was the highest level language I ever used. It was expressive, meaning I could take an idea in my head, and implement it in perl with the least friction of any language.

When I worked with other people's perl, I found they were mindful and cared about what they were doing.

But the way they thought was sometimes almost alien to me, so the expression of their thinking was a completely different type of perl, and it was lots less readable to me. And frequently the philosophy of what they wrote was backwards or inside out from what I would do.

Now I have replaced perl with python day to day and although implementation of code seems a few steps removed from my thinking, it seems that other people's code is more easily read and understood. (this is just my opinion)

  • As they say, with perl there's more than one way to do it (TMTOWTDI) and with python there is only one way.

    Both approaches have their merits. Like with maven, where I once saw a question on a forum that was like "how do I do X?" and the reply was basically "You can't, don't try to do so, as that's wrong".

    • There is usually more than one way to do it in Python, too. For example most people's Python fizzbuzz seem pretty different from mine:

        def fizzbuzz(n, *args):
          cur = ['' for x in range(1,n+1)]
          for m, postfix in args:
            cur = [y+postfix if x%m==0 else y for x, y in zip(range(1,n+1), cur)]
          cur = [str(x) if y == '' else y for x, y in zip(range(1,n+1), cur)]
          return cur
      
        print("\n".join(fizzbuzz(100, (3, 'fizz'), (5, 'buzz'))))

      3 replies →

  • That's an interesting point that could be even more interesting with some examples on both languages.

    • I don't have any code examples, but I recall:

      - a lot of things I did in perl ended up using regular expressions

      - in comparison python use of regular expressions is not first-class so many problems would use string functions instead. (although r'<expr>' was less ambiguous wrt quoting rules)

      - in perl path manipulation would use regular expressions

      - in python I embraced os.path

      - I would use oo in python, but rarely in perl

      - argparse

Maybe what we need as programmers for collective professional defense is to only LLM-code in Perl.

At some point when the LLM fails, you'll need a real programmer to figure it out.

But IMO, LLMs are code generation, and code generation always fails at some point when the pile of generated code topples, no matter the language.

The amount of bad enterprise LLM code that will be cranked out in the next few years is going to be fascinating to watch.

> I don't miss perls halfarsed function args.

You mean you don't like writing things like...

    sub foo {
        my ($a, $b, $c) = shift;

?

  • Indeed!

    It just grinds my gears that _I_ need to check to see if the caller has given me all the required bits. That seems like something the language should do.

    I understand that it does give you a lot of flexibility, but Hnnnnnnnnn

    (from what I recall object oriented perl doesn't give you this flexibility, but I'm not sure, as I never really did it. )

    • Object oriented perl gives you exactly the same flexibility.

      If you have a module called "My::Module", and you call "My::Module->some_method", then you'd implement that like:

          sub some_method {
              my ($pkg, @args) = @_;
      

      i.e. the module gets passed (as a string) as the first argument. You can then call

          $pkg->some_other_method;
      

      And similarly, if you have an object "$foo" you would call it like "$foo->some_other_method" and implement it as:

          sub some_method {
              my ($self, @args) = @_;
      

      i.e. the object gets passed as the first argument. And you can call "$self->some_other_method" with it.

      A minimal class is just:

          package My::Module;
      
          sub new {
              my ($pkg, %opts) = @_;
      
              my $self = bless \%opts, $pkg;
      
              return $self;
          }
      
          1;
      

      Don't let them tell you you need Moo or Moose or Mouse or fields.pm. Hand-rolled objects is the way :)

  •   Yes, I hate to write
    
      sub foo($$$) {
        my ($a, $b, $c) = @_;
      }
    

    Where @_ is array of arguments, and ($$$) is function prototype (3 scalars are expected).

    • Perl has subroutine signatures now. You can write

      sub foo ($x, $y, $x) { ...}

      It's just syntactic sugar, so you still can't pass in multiple lists, and the list must be the final parameter.

  • Not sure if you've deliberately put in two bugs there haha

    1. shift only shifts off the first element.

    2. (if classify this as a bug) using $a and $b are frowned upon because they're the default variables when using sort.

Perl’s function arguments no longer require you to shift or to access the @_ array. There are even proper argument signatures now. There’s also continuing improvements in putting a one true way to do objects into the core language, so you don’t have to bless a hash, use Moose, or Moo, or use Object::InsideOut (or any of a dozen other non-core modules).

All that old code still works, though.

Yes, as did I! When I did POPFile (which is 100% Perl) I was really, really careful to make it readable and maintainable.