This will sound silly, but it only recently dawned on me that a code library isn't just for finished, polished code. It can also be for code that are works in progress that may not be pretty and far from perfect, but is still useful in helping you get actual work done. This summarizes a basic recipe for setting up a "working" library of modules and my workflow for developing these modules.

But first, what exactly do I mean by a "working" library? It's a library for utilitarian modules that you have written to help you in your day-to-day coding or work. The modules are not polished enough or are too specific to release as a formal distribution to CPAN. But they still need tests to make sure they work. For example, I have a collection of modules I use to help me set up and configure WordPress sites on my local machine in Docker. Since these are for my own use, I don't bother setting up a git repo for these module or track issues with them or version them. I just write a test, update the module to pass the test, and then make use of the module right away. Except for comments, I don't bother documenting the modules and most of them are simple enough where the documentation isn't really needed. The goal is to keep the admin overhead of these modules to a minimum while still ensuring the modules work well enough.

So here's what I did to set up my working library:

  1. Created a new directory for my modules. I have it set to ~/perl5/working_modules
  2. Added this path to the $PERL5LIB environment variable
  3. Added my modules to this directory
  4. Added a test directory to working_modules for holding tests ~/perl5/working_modules/t. But this directory can be anywhere on your hard drive. It doesn't not have to be in working_modules.
  5. Placed any tests into the t directory. I organized the tests using the same structure as my modules in the working_module directory. So a module called Some::Module, has tests in the working_modules/t/Some/Module/ directory

The workflow is simple test driven development: First, write a test in the appropriate test file for the module you are going to add a new feature to and then write the code and run the test. Then get right back to work. I no longer have to worry about whether my tests are including the right path to my modules. Since all my modules are in the $PERL5LIB, I don't have that headache anymore. Before using a working library, I had modules spread out all over my hard drive for different projects I was working on making things very difficult and my code not very reusable or easy to find. Now I just throw a use statement into the code and I'm done.

This obviously isn't anything groundbreaking or new. But if you're anything like me, it took a while before it dawns on you that useful, utilitarian code can dispense with a lot of formalities and you don't have to wait for it to be perfect or even good before you put it into a library.

$PM = "Perl Monk's";
$MC = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar Parson";
$nysus = $PM . ' ' . $MC;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Tip: Create a "working" perl lib for your personal use
by choroba (Cardinal) on Jan 05, 2024 at 20:43 UTC
    > I don't bother setting up a git repo

    Depends on what you call a repo. I run git init almost everywhere (including my $PERL5LIB to easily switch between various versions of CPAN modules), and as I own several computers (desktop + 2 laptops), I usually need everything on all of them. GitHub nowadays offers private repos for free, but I still use a USB flash drive from the times when it didn't where I create --bare repos for all my personal projects and set them as remote origin.

    > I organized the tests using the same structure as my modules

    Interestingly, we used the same strategy at $job - 2. There were hundreds of modules and it was surprisingly easy to find the corresponding tests for the file one had just modified.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Tip: Create a "working" perl lib for your personal use
by InfiniteSilence (Curate) on Feb 01, 2024 at 00:36 UTC
    "This will sound silly, but it only recently dawned on me that a code library isn't just for finished, polished code..." Hmmm...the thing to remember about putting code in modules is that once you start to rely upon that code you will become afraid to change it unless there are tests to somewhere to support changes.
    package Foo; sub returnANumber { return 66; } package FooUser; use Foo; if (Foo::returnANumber() < 82) { # do something } else { # do something entirely dependent upon returnANumber being an intege +r > 0 && <= 100... }

    Recommendation #1 is to write tests and package them alongside your scripts to ensure that one travels with the other. Or you could just store them inside a DATA segment at the end of a script...

    #!/usr/bin/perl -w use strict; use Getopt::Long; my ($aa, $bb, $diagnostic) = (undef, undef, 0); if (@ARGV){ GetOptions('aa=s'=>\$aa, 'bb=s'=>\$bb, 'diagnostic'=>\$diagnostic); } if ($diagnostic){ my $test = ''; while(<DATA>){ $test .= $_; } eval($test); die 'Ran tests. Done.'; } 1; __DATA__ use Test::More qq~no_plan~; ok(1==1,'basic'); 1;

    "Then get right back to work. I no longer have to worry about whether my tests are including the right path to my modules..."

    Unfortunately this is the problem I run into all to often. Developers and support people do all of the right things...they write tests, they modularize their code; they store things in separate libraries on a hard drive. All good. Problem: what happens if you take another job?

    I get it. People say, 'well...I wrote that stuff to facilitate my work; the next person is just gonna have to figure out my stuff or cook up their own...' Yep. And the next person shows up on Perlmonks with 30 questions about how X, Y, and Z works.

    You specified your workflow and even enumerated the points. Here is where I think it falls short:

    1. Stop writing code and start writing down what you want code to do (use psedocode/perldoc, whatever). Then look in CPAN for modules that do what you want. Ask if they are recently modified or easy enough for you to understand that you can modify them yourself it they break. Then actually use the modules.
    2. Add your own tests. You are on the right track there.
    3. Everything, everything, everything must go into some form of version control that is backed up on some redundant data storage away from your machine. No exceptions whatsoever. That includes scripts and utilities. When you are away from work you are likely learning. When you learn you get some code. When you return to work you'll try to remember that code. Guess what...you lost it. That is why even your personal stuff must follow this rule. The company's stuff is company property. If you didn't back that up you misappropriated company resources.
    4. Always periodically rethink our workflow. I check my history file all the time kind of like how a Russian submarine does a 'crazy Ivan' to see what I am doing repeatedly. It is odd how we don't realize that we do something that could be scripted saving us cumulatively hours per month and weeks per year.

    The last one is a bit tricky because it depends a lot on the industry you are working in. If you are in some engineering firm you might find that there are numerous conditions that no one has thought about that will force you to refactor code a lot. In that case you might find you have to keep your code in some smaller pieces that can be mashed together at some later point.

    Celebrate Intellectual Diversity