k as in knife

Many moons ago my earlier version of my blog had this list I use when spelling things for people over the phone. I managed to find it at archive.org and thought I’d repost…

  • a as in aisle (or aye)
  • b as in bdellium 
  • c as in czar
  • d as in djibouti
  • e as in eight
  • f as in fjord 
  • g as in gnaw
  • h as in herb 
  • i as in isle (ioan was recommended but I’m split on this one)
  • j as in jalepeno
  • k as in knife
  • l as in Lladro (llano was another suggested alternate)
  • m as in mnemonic
  • n as in Nguyen (or ngwee)
  • o as in oestrogen
  • p as in pneumatic
  • q as in queue (or quay – pronounced ‘kay’)
  • r as in ???? 
  • s as in scene (or sea)
  • t as in tao (pronounced with the ‘t’ as a ‘d’) 
  • u as in uakari 
  • v as in “Five” (as in the roman numeral five – yes, a bit weak, but still gives the level of confusion suitable for phone conversations) 
  • w as in wrench (or ‘why’)
  • x as in xenon 
  • y as in yttrium (Yvonne might work better for the phone?)
  • z as in ????????

Got some ideas to help fill in the blanks? Let me know!

Laravel is sending duplicate emails!

So… I wrote a previous post about how to prevent duplicates, but this post is about a different type of duplication problem. I encountered this issue about 18 months ago, and asked around, and few people seemed to know what I was talking about, and I don’t specifically see it mentioned in the docs. So.. here goes.

// Laravel 5.7 and above, IIRC
// haven't checked on older versions
$mailable = new MyMailableClass($$data);
Mail::to("s@kimsal.com")->send($mailable);
Mail::to("j@kimsal.com")->send($mailable);

If you run the above code, the system will send an email to s@kimsal.com. The system will then send a second email with to both j@kimsal.com *and* s@kimsal.com. Why?

Behind the facade, the $mailable class has a ‘to’ list of recipients, and every call to Mail::to will *add* to the mailable’s recipient list, not clear and start over. This is certainly not intuitive, and is likely the root cause of a lot of the posts I’ve seen about “duplicate email” behavior. Certainly there can be other causes, but I’ve hit this one personally, and know it was a bugger to figure out.

The fix? I only know of two fixes.

  1. If you’re really sending the exact same thing to multiple addresses, you can send to one array of addresses. The downside is that each person will see the other recipients’ addresses. In some cases, this won’t matter. In others, it may be a big privacy issue.
  2. You can also just create a new mailable each time.

I help this helps someone 🙂

Laravel DeferrableProvider not working

Title was a bit clickbaity but perhaps this will save someone else some time.

Put simply, the ‘register’ method on a service provider class is always called when executing from a php artisan context. This is not explained anywhere in the service provider documentation. The ‘Deferred Providers‘ section of the documentation does not explicitly call this out, and it cost me some time last night debugging an issue.

*WHY* this is, I’m not quite sure, but it can certainly cause some confusion as to why code operates one way via http requests and one way via console execution. If/when I have time I may add a bit more to this, but just dropping this note here for now…

Laravel prevent duplicate emails

On a recent project I misread a ticket and understood it as a need to prevent duplicate emails being sent (within a certain amount of time). I’d realized the ticket was calling for something different, but I finished some investigation on what it would take to prevent potentially accidental duplicate sends.

My first thought was to write a plugin for the swift_mailer component, which … I did, but then realized it may be easier to hook in to the event system at the Laravel level (vs down lower in the mailer plugin level).

I ended up adding an event listener in EventServiceProvider.php

protected $listen = [
'Illuminate\Mail\Events\MessageSending' => [
'App\Listeners\PreventDuplicateEmail',
],
];


The PreventDuplicateEmail class

namespace App\Listeners;

use Illuminate\Mail\Events\MessageSending;
use Swift_Message;

class PreventDuplicateEmail
{
static $done = [];

public function handle(MessageSending $event)
{
$message = $event->message;
$hash = $this->hash($message);
$toRecipients = $message->getHeaders()->getAll("to")[0]->getNameAddresses();
foreach($toRecipients as $email=>$name)
{
if(!array_key_exists($email.$hash, self::$done))
{
self::$done[$email.$hash] = time();
}
}
}

public function hash(Swift_Message $message)
{
$subject = $message->getSubject();
$body = $message->getBody();
$from = array_key_first($message->getFrom());
$combined = $subject.$body.$from;
return substr($subject, 0,20).":".substr($from,0,20).":".sha1($combined);
}

}

This isn’t finished – to prevent sending, use a ‘return false;’ in the listener. And determining the window – 5 minutes? 1 hour? – that’d be up to you. You could store everything in a database table and check there as well. Because I’d misread the requirements, I didn’t completely finish this, but hopefully this gets you a bit closer if this is what you were looking for…

Web color and font detection

I came across an idea on someone’s blog a bit ago asking for a display of colors/fonts used when bookmarking a website. This was someone speaking from a web designer perspective – curating a list of sites for visual inspiration isn’t uncommon, but knowing a bit more about the details of the sites might save a bit of time if you decide you want to use the same combination of colors or fonts.

I put together a quick service as a proof of concept. You can give it a URL and it will retrieve a screenshot, then parse out the fonts and colors used on the site, and display them to you, usually in under 10 seconds.

Quickly get the fonts and colors for a web page

A few changes may be coming in the next day or two, but this serves its primary purpose for my needs right now. Shoot me an email and let me know what you think…. michael@kimsal.com

installing canjs 5 via npm bug

Was looking at canjs5 earlier, and tried to install via the instructions.

I’ve got npm 6, but there’s a dependency in “can-connect” (must be related to canjs base) which requires npm 3 (only). This was set in 2016, and hasn’t been fixed. I have to wonder how people have been installing and using canjs in the last year or so… ?

I created a bug with canjs, but the ‘fix’ if you happen to get here searching for this bug…

npm install can@5 –save –engine-strict=false

back to some mobile

I’d done some small- to medium-sized projects in ionic a couple years back, and titanium/appcelerator before that, but have been focused on server-side and browser-based work for the last year or so. I’m jumping back to mobile/hybrid, and seeing what’s new.

I’ve been a fan of vuejs for a couple years now, and Ionic 4 now ‘officially’ supports vuejs integration. I was waiting for this for a while – I could take 2 stacks that I know already and be more productive. However… the ‘official’ support seems a bit … weak at the moment, and Angular is still king in the Ionic world. I started a demo project with all the latest angular/ionic stuff, and may put a link to that here if/when I get done with it. I’m just… not a big fan of Angular – it all feels very bulky compared to Vue, so that project may not get done.

To that end, I’ve had some interest in Quasar recently. This looks like “ionic for vue” more or less, but I’m a bit hesitant to jump too far in, mostly just because of time. But it’s on my radar.

Couldn’t remember this name – Framework7 – took a bit of googling to get to it! My friend Mitch threw this at me last year, an it’s now back in my ‘to do’ list to review.

NativeScript – they have ‘official’ support for VueJS (or maybe it’s ‘unofficial’?). This … I dunno – I spent a bit of time last fall looking in to it but it never clicked. Felt a bit like Titanium/Appcelerator perhaps? But I hear/read good things about it, so it’s back on my list.

Svelte.dev – came across this a couple months ago, then my brother mentioned it again recently. I’ve done some basic ‘hello world’ stuff, and maybe a bit further than that. The ‘single component’ aspect feels a lot like Vue components, and the ‘stuff done in the compile step’ is an interesting angle/twist. This video shows a recent talk and is worth watching to understand svelte and the thinking behind it more.

I’m off to dive in to one of these in the next few minutes, just to see how far I can get in 30 min. If I have anything of interest, I’ll follow up 🙂

Python 2 to 3…

Not a python person (used it in some projects, but it’s not my main tool). That said, I’ve been watching the “2->3” migration horror stories and woes for several years. In 2014, the “2015 deadline” for Python 2 deprecation was pushed back to Jan 1, 2020, so it’s once again starting to loom large.

I came across this little gem which may be one reason why so many people didn’t try to upgrade to 3 from 2…

The round() function rounding strategy and return type have changed. Exact halfway cases are now rounded to the nearest even result instead of away from zero. (For example, round(2.5) now returns 2 rather than 3.) round(x[, n]) now delegates to x.round([n]) instead of always returning a float. It generally returns an integer when called with a single argument and a value of the same type as x when called with two arguments.

So any code you had that relied on ’round’ function in Python 2 would automatically work differently when moving to 3. That may be a lot of code to audit/test/change!

(Edit: have learned this pattern is “banker’s rounding“. Still not sure it warranted such a change (or why the algorithm wasn’t pointed out as “banker’s rounding” in the change docs I’d found).

Similarly, “print” was changed from a statement to a function.

2.x: print "The answer is", 22 
3.x: print("The answer is", 22)

The 2.x style simply doesn’t work in Python 3. Again, that would be a hell of a lot of code to review/audit/upgrade, for no functional benefit.

Have you made the jump to 3? Did you just start with 3? Did you have to do a migration? Was it as bad as it sounds?

js promises are the new threads

Years ago I read that ORM was the Vietnam of Computer Science… That was certainly not the first time I’d read a pithy comparison, but it stuck with me.

I had lunch with a friend last weekend, and reminded him of a lunch many years earlier. This was probably… 2008. I’d picked him up for lunch, and our lunch was cut short with “I gotta get back – we’re having some major thread issues on a section of the code, and we’re behind on getting this shipped”.

This was Java, and it was 2008. There were behaviour bugs that no one could track down outside of “this is a threading issue”.

It came to mind because I was recently (the day before) dealing with some inherited JS that was heavy on deferred/promise/async/callback stuff. Guess what? Something wasn’t working. In the course of adding a new feature, I stumbled on something that looked like it’s been non-functioning for months, if not years. Low priority UI thing, but… frustrating.

I spent time trying to track it down – no luck. I reached out to one of the guys who wrote some of this, and has used the codebase (and built on top of it) for years. At first he thought it was a misunderstanding on my part – I’m new on this project, and that’s been the pattern. “Oh, Mike just doesn’t get this”. 10 minutes later I got something like “this is baffling – it’s just not working”. He spent another half hour or so trawling through everything he could think of. No joy.

I write this not with some great words of wisdom, or some silver bullet to cure everything. You use JS frameworks, you’re probably going to be using some degree of callbacks. But… in my old age, I may be more of a luddite than earlier. I avoid callbacks when possible (and again, I know it’s not always possible). But as I get older, I’m trying to optimize for clarity and understandability, and I don’t think promise/callback style development aids that, not on its own, anyway. You have solids tests, sample data and documentation around the code? Go for it! Absent those (which most people don’t do) it’s a harder sell for me.

And… 10 years ago doing Java, I shied away from reliance on threads wherever possible. Bottom line, to me, it’s just difficult to reason about. And, from what I’ve seen, it’s actually difficult for other people too (multiple anecdata from 20+ years of various development work). I’m just not sure people recognize that something is actually adding some potentially unneeded complexity and that is difficult to reason about and test, vs something just being difficult because it’s, perhaps, somewhat new to them.

Again – these tools all have their place, but I tend to view these as necessary evils vs “go to” first practices when architecting something.

misophonia, ears and colored noise

Sorry… couldn’t think of a better title!

Years ago I self-diagnosed with misophonia. Certain sounds trigger me in to difficult-to-control feelings of anger. I’d stop short of using the phrase ‘rage’ exactly, but when others use it, I know what they’re meaning. This started with sounds of others eating food (and oddly, even my own eating sounds on occasion, although that’s not common) when I was a child, and it’s been a steady thing since then.

Normally it’s crispier things – chips, crackers, etc – which trigger the reaction, although chewing with an open mouth is another trigger, as well as gum-chewing.

One big thing that helped as I was growing up was simply my own ability to control my environment. Being able to leave a table for a few moments is often enough to get things back to normal (in my head), and my condition is nowhere near as debilitating as it is for others.

Over the years something else that became a trigger is road noise – large trucks driving past – loud engines, motorcycles, rumbling, etc. Unfortunately, we live close to what’s become a main thoroughfare in our county – one of the few ‘cut through’ country roads which was basically untravelled 14 years ago. We’re fairly close to the road – only 4 houses in – so this has become more of an issue for me over the past 8 years or so.

The biggest help has been wearing earbuds running a whitenoise generator to help get to sleep. I had weeks where I couldn’t get to sleep at all, and it became a nightmare to deal with. Unfortunately, sleeping with earbuds tends to destroy them – I went through a couple of pairs of Bose QC20 (noise cancelling earphones which are a godsend for misophonia folks) before deciding to stop sleeping with them. I now get cheap $4 pairs from the dollar store and they last a couple of months. They’re samll enough to allow for sleeping on my side, and can get buried deep enough so as not to require loud volumes.

I’ve used this whitenoise app for years, and eventually upgraded to the paid version. There’s not much difference, but for all the relief it’s provided over the years, the authors deserved the few bucks it cost. They also have a desktop version I use (with the QC-20) for day to day work stuff at the office. The combination has really been a life-changer for me, and if you’re dealing with misophonia, consider it if you haven’t. Earbuds, whitenoise and a degree of autonomy to change my surroundings when needed has been instrumental in dealing with this. And yes, even changing house surroundings – we’ve been looking to move for a bit now, and sound is a primary consideration for the next house.

So… colors of noise? What’s that? I know people know the term “whitenoise” and I’ve been using it as a general term for ‘masking/hissing noise’, but I usually use brown noise, or a mix of brown/grey, in the app I mentioned earlier, and it’s quite … soothing? White noise itself is rather “tinny” to my ears, and actually hurts a bit after a few minutes. I can listen to grey or brown for hours, often with mixing in some rain or thunder sounds, and it’s fantastic. There’s multiple ‘colors’ all with different frequency characteristics – this article describes them in more detail.

If you’re dealing with misophonia, you have my sympathies. The reddit forum, as small as it is, has been one of the few social places where I’ve found you can find some support. Good luck to you.