Sunday, March 7, 2021

php was such a nice step over perl

I get a little defensive over my use of PHP (and keep a link Taking PHP Seriously handy) - I sometimes wish my rented server had more options for doing serverside stuff in javascript, say, but PHP is both convenient and performant.

My server-based blog/diary/database still uses a lot of legacy Perl CGI - if it ain't broken why fix it? - but lately it HAS been breaking, logs showing "Cannot allocate memory: couldn't create child process" errors. So I figured it was time to update things to PHP and get rid of the CGI dependency. 

(I still owe a debt to Perl - see what perl taught me (in the early-mid-90s))

One thing about PHP - it's such a mature environment, in terms of almost every utility you'd want is baked into the language - no CPAN or npm hell or hacking up some regex, it's just there. Case in point, here's a legacy Perl function for my private diary (a bunch of flat files, one per day) I'm porting now

sub dateGoneOrEmpty{
    if(! (-e "entries/$justwhen.txt")){
	return 1;
    open(READ,"< entries/$justwhen.txt");
    my $buf = "";
	$buf .= $line;
    close READ;

    if($buf =~ /MORE/){
        return 1;

    if($buf =~ /\S/){
	return 0;
    return 1;

The "$justwhen" is a datestamp used as filename... this function returns 1 if the file doesn't exist, is empty, or just has the word (all caps) MORE in it (an old hack I used when I knew I wanted to come back and put in more details in a day's entry)

But the syntax is kind of terrible! It's Perl's wonky/shell based way of passing in variables, rather arcane "-e" for file test, use of 1 or 0 for true/false, and doing everything by regex (well that last is not terrible terrible but still) That all reflects Perl's history drawing from shell programming, which I never did much of.

Here is the same logic recreated in PHP

function dateGoneOrEmpty($justwhen){
    $filepath = "entries/$justwhen.txt";
    if(!file_exists($filepath)) return true;
    $buf = file_get_contents($filepath);
    if(str_contains($buf,"MORE")) return true;
    if(ctype_space($buf)) return true;
    return true;

(Not optimized at all, just trying to formally recreate the old behaviors)

That's so much cleaner! I also love how PHP splits the difference with globals... you can just write a simple script and everything is a global, but if you reference a global in a function - you can do that, you just have to declare it as "global". That's so much better than javascript's "well we'll just throw it on window." and/or  "just assume there is a global of this name"

(The one thing I loved in Perl I wished showed up elsewhere: use of "eq" and "ne" "gt" and "lt" for string comparisons... I love the mnemonics - it's a string, so the operator is more string-ish)

Thursday, March 4, 2021

note to self: bold tags can be used to select different font files

I implemented support for customizing font-family's with the assumption I could use the font-family name as a unique key, but that was a misthink; I'm not sure it's frequently advisable, but there's a use case of having different font-families where like you pick one file or another based on, say, a <b> tag:

I made up a simple test page

@font-face {
    font-family: 'Foo';
    src: url('AkayaTelivigala-Regular.woff2') format('woff2'),
        url('AkayaTelivigala-Regular.woff') format('woff');
    font-weight: bold;
    font-style: normal;
    font-display: swap;

@font-face {
    font-family: 'Foo';
    src: url('Stick-Regular.woff2') format('woff2'),
        url('Stick-Regular.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;

Later on then, this HTML uses two different fonts files:

<div class="foo">Same Font Family <b>
But A Different File For Bold</b></div>

Of course, the browser can do a pretty good job faking up a "bold" even if it's coming from the same file.

Wednesday, March 3, 2021

overlapping sprints to deal with the harsh realities of scrum

Scrum, an "agile" methodology to make the rhythm of software development more predictable, tends to be built on some iffy assumptions.

Some of these methodologies assume that any given ticket will be a equally as difficult no matter which dev, qa, or designer works on it. (Kanban, in its purest form of "the top ticket is the most important thing that should be picked up next" also falls prey to that 'everyone is interchangeable' fallacy, but in practice people don't have to scoop the ticket right on the top, they'll go down a few to find one that makes sense for their role.)

Some teams avoid thinking of people as interchangeable parts, but fall prey to completely ignoring the "Gant chart"-like dependencies within a sprint - the way many tickets will need some work by Designers, which will then be handed off to be implemented by Developers, and then finally to QA (with some time needed for Dev to fix what QA finds)

(But at least such teams have QA has its own thing! - the trendy thing to do has been to say "devs QA their own work" - armed with their own sense of diligence and the power of automated tests, but A. it's really hard to get someone to be good at hunting for something they don't want to find, i.e. ego-bruising bugs in their own code and B. for automated tests.... if they could have thought of went wrong ahead of time they would have already fixed it in code! So tests are mostly good to say what was developed hasn't been broken over time. (There are some other things tests are good with, but still, in my experience they aren't as load bearing as people want to pretend, and are much more brittle and prone to needing to be fixed than the code itself.))

Anyway. Here's theoretically what a sprint should look like:

That's a weird setup, right? What is QA doing the first part of the sprint? What is Design doing the last? In practice there are always things to be doing, extra chores, light prep for future sprints or learning or useful tasks, but I find it bizarre this kind of dependency isn't accounted for in the system. And of course, let's be honest, thanks to human psychology, this is more what a sprint actually looks like:

QA always gets squashed! Devs are thinking more in terms of the whole sprint rather than aiming to get done halfway through. And so the system fixes itself by carrying over to the next sprint... but that feels bad, like failure, even though the failure is more in the design of the system than in the people doing the work.

The sanest, most clear-eyed response I've seen to these problems was at Alleyoop, a little subproject of Pearson Education that unfortunately never found its sustainable business model mojo. They would do overlapping springs, something like this:

I'm not sure how the naming actually worked (overlapping full sprints vs "subsprints") but hopefully you get the idea: from the devs point of view, at any given sprint, designers were prepping stuff for dev that would be coded in the next sprint, and QA was checking on what was dev'd up the previous sprint.

The trouble is, most tools companies rely on don't model this particularly well. (Alleyoop was well in pre-COVID times and independent, so it was free to use good old "stickies on a white board" without having to use online tracking tools.)  And it's a tough sell. But at least it acknowledges that any given ticket has dependencies in time, and if you want to keep everyone productive, you should include those dependencies in your system.

Monday, March 1, 2021

Sans Forgetica, a font to remember

 Sans Forgetica, a font to remember

Having to fill in the gaps might engage better, more remembering parts of your brain! Interesting free font.

change your apple pencil tip

 I haven't thought much about Apple Pencil tips - honestly they seem to last a long time! And it wasn't clear what was "consumable" about them, but after noticing very bad responsiveness, ordering new ones, and then reading 5 Signs it’s time to change your Apple Pencil Tip - I finally notice what's happening, that you don't want a hard surface that might scratch your iPad screen, so the tips give way first, but slowly. 

The "Pencil" name is more appropriate than I realized!

Anyway, they're pretty cheap to order online.

Wednesday, February 24, 2021

cool storybook cookbook

This page of storybook HOWTO/recipes lets us do a trick in storybook... we were already using a set up in preview to style components, but we wanted to be able to include 


  <Story name='Some specific argument' args={{ children: 'Button' }}>

without that Story showing up in the sidebar. (Detailed request from our PM)

Tuesday, February 23, 2021

two pieces on keeping it simple

I am not a fan of frameworks in general. 

Here's a piece on The web didn't change; you did and reminding folks that for personal projects, nothing is keeping you from PHP/HTML and Javascript. 

Even for more professional settings, there's this piece on The Case Against Web Frameworks. Browsers can do so much today, and ECMAScript/JS has so much great syntax built in.

I've been using PHPwebhosting for over a decade now (and a similar site before that.) It's such a great investment, a site I can ssh into and put up whatever fool PHP I want! 

I worry about the disconnect between the tools I use "for fun" and the stuff I use for work - one of my secret sauce advantages over the years was using the same kind of stacks for both - but it is what it is. And maybe I'll slowly convince people at work to keep it simple as well...