MacBook, defective by design banner

Put the knife down and take a green herb, dude.


One feller's views on the state of everyday computer science & its application (and now, OTHER STUFF) who isn't rich enough to shell out for

Using 89% of the same design the blog had in 2001.

Back-up your data and, when you bike, always wear white.

MarkUpDown is the best Markdown editor for professionals on Windows 10.

It includes two-pane live preview, in-app uploads to imgur for image hosting, and MultiMarkdown table support.

Features you won't find anywhere else include...

You've wasted more than $15 of your time looking for a great Markdown editor.

Stop looking. MarkUpDown is the app you're looking for.

Learn more or head over to the 'Store now!

Tuesday, March 21, 2017

If you're not using Chrome Dev Tools JavaScript Blackboxing, you're doing yourself a serious disservice.

I've been working with some stuff that's heavily React and mobx-i-fied, and constantly get dumped into those third party libraries. With Blackboxing, I can put those and any other third-party libraries into the black box, and will automatically jump over all of that code.

It's beautiful to skip over all third-party libraries. I kid you not. Beautiful.

What I hate is that this stuff seems to have been around in at least pre-release form since 2014!


Labels: , , ,

posted by ruffin at 3/21/2017 01:04:00 PM
Wednesday, March 15, 2017

Remember how I took the time to show how to map Gvim to F1 in Visual Studio? I think there's probably a much better way: VsVim.

I installed it, forgot, had Win10 "helpfully" reboot, and suddenly saw a phat cursor in Visual Studio. Took me a second, but then it hit me -- I'm VImming in VS.

Only gotcha -- I needed to create a new environment variable, VIM, to put the path to my normal _vimrc file so that VsVim could find it.

But after that, so far, beautiful. Embarrassed I didn't hear about this one sooner. Would've saved me some time. That's one of the big reasons I use Sublime Text. I mean, it's a great text editor in lots of other ways, particularly fast searches, multiple cursors, and nice plugins, but it's vintage mode that hooked me quickly.

In any event, a nice upgrade for VS so far. And 281 reviews averaging essentially five stars ain't bad. My only complaint so far? No gqgq. For that, I'm back to F1.

In other news, got word of my second MarkUpDown Microsoft Store payout today. That's always fun to get, even if it won't cover my already exceptionally trivial marketing budget. But it is growing. That's cool.

Labels: , , ,

posted by ruffin at 3/15/2017 09:44:00 PM
Monday, March 13, 2017

Jay Bazuzi was talking about how to make the work of distributed teams run more smoothly, and there was a term he used that I thought deserved a little googling...

There are a bunch of known good practices to help distributed teams not suck too much. Doing them won't get us to "awesome", but at least we can get up to "not sucky". So let's start by writing down these practices:

  • Recognize the expression of Conway's Law: limited communications affect software architecture

As it turns out, Conway's Law is pretty interesting. Here's some more, from Demystifying Conway's Law on ThoughtWorks:

In "Exploring the Duality between Product and Organizational Architectures", a study by The Harvard Business School carried out an analysis of different codebases to see if they could prove Conway’s original hypothesis as applied to software systems. In it, they took multiple examples of software created to solve the same purpose (for example word processing, financial management and database software), and compared the code bases created by loosely-coupled open source teams, and those created by tightly-coupled teams. Their study found that the often co-located, focused product teams created software that tended more towards tightly-coupled, monolithic codebases. Whereas the open source projects resulted in more modular, decomposed code bases. [emph mine -mfn]

The real take-home comes just a little later, though, I think:

You may see tensions in your own organizations where your structure and software are not in alignment. You may have seen for example the challenges involved where distributed teams try and work on the same monolithic codebase. [emph me again -mfn]

That the work of distributed teams -- or, if you ask me, any team -- can be coordinated more easily when you take the time to clearly define the interface surrounding their work seems like a truism.

Though I'd never given the converse enough thought. If you have a widely distributed [read: "entirely remote"] team that doesn't tend to communicate, having a monolithic codebase, especially one without documentation, can absolutely hamstring development. Or, at best, it means that your team will tend to ignore what exists and replace with whatever seems best.

If you start eating away at the monolith in good, interfaced, discrete chunks, however, that's probably about as good as means of erasing it as you can get.

Regardless, I think the lesson here is that the downfalls of poorly documented, monolithicly designed codebases are compounded in easy to identify and productivity unfriendly ways in distributed/remote work environments.

Say that three times quickly. Even better: Remote environments require well factored code.

Labels: , , , ,

posted by ruffin at 3/13/2017 08:30:00 AM
Tuesday, March 07, 2017

I like to listen to artists by album, and I like to pick which album to start from. No luck in iOS Music-land. From

OMG Seriously! Far out, Apple have done bad! 

Thanks for that though :)

That was not particularly discoverable.

But it gets worse...

That certainly works, but the albums are still sorted in reverse chronological order (and have been since iOS 7).

So bad. Big league! This has driven me crazy for years. You'd think Apple could get the iPod part right by now.

I tried Cesium. Something eventually talked me out of it... I think, in addition to the fact that Siri only uses Music, that I recall a few nasty crashes.

Doesn't seem like a music app would be this difficult to get right. There were lots of decent ones on OS 9-, for instance.

Labels: , , ,

posted by ruffin at 3/07/2017 07:34:00 AM
Monday, March 06, 2017

As a general rule, I try to stay away from Daniel Dilger's written pieces. They're usually entirely too long for the points they're making (sound familiar? ;^D), and each has about five syllogistic fallacies that drive me bonkers. Luckily, they also tend to have such obviously biased, clickbaity titles that they're easy to filter from your RSS feed.

Accidentally stepped into one this morning. Lots to disagree with that's not worth the time, but I did want to cover this one, which I've heard from less sensationalist, smug writers:

From Editorial: The future of Apple's Macintosh:

Mac Pro

The Late 2013 release of Mac Pro may have been a mistake. Its design wasn't readily upgradable, but Apple also lacked the sales volumes to warrant regular significant update cycles. If a cycle is too long, the benefits of product cycles described above begin to evaporate. It may have been better for Apple to have designed a system other vendors could upgrade, with room for standard PCIe graphics cards and perhaps even CPU packages. [emph mine]

Though not having a PCIe slot is a fairly consistent complaint that's recently gotten a lot of press, I don't think that's the problem. The problem is that the silicon inside the Mac Pro hasn't been updated since 2013.

The PCIe complaint is really just an extension of the argument that Apple's been slack with updates. Asking for PCIe is a little like saying, "If you're not going to stay current, let me do it myself!" (Of course, that's also, imo, why it's smart to add a PCIe slot. But that's another argument...)

Here's DED's logical faceplant: There's plenty of volume for Apple to update the innards.

The enthusiast's motherboard & GPU market

My whitebox' motherboard

Every few years, I upgrade my whitebox tower; it's a computer I build myself. Every time I do, I wade through tons of motherboard options. Though the one I have in there now is still for sale on NewEgg, it's from some squirrelly third-party selling out of date hardware for over twice its original price, iirc.

Same thing with video cards. There are tons of companies rebadging Nvidia's and ATi's latest in different configurations, turning over almost completely each year. (And here, my crappy card is out of stock.)

Are you really going to tell me Apple can't afford to make just one new motherboard and video card each year?

My point is that these enthusiast computer components usually don't last long on the marketplace. You have a slew of options at any one point, but in 6-12 months, no matter how intelligently you shopped, what you bought is usually long in the tooth, replaced by one or more upgraded boards by each company in the direct-to-builder motherboard category.

Fewer Mac Pros than enthusiast Asus boards? Rly?

Does anyone really think Apple sells fewer Mac Pros than ASRock sold of their "H97M Anniversary LGA 1150"? I can't imagine that's the case for a second.

And that's where Apple's let you down. You can build an all-in-one pro model if you keep it relatively recent, and you keep it recent by upgrading the mother- and video card daughter -boards. If Apple's going to release a Mac like this, it has to commit to upgrading the motherboard, processor, and GPU options at least yearly. No redesign of the outside needed.

I understand there are issue with the trash can. Maybe there's not enough airflow for cooling a GTX 1080 with the trash can's single giant fan. Maybe it's not as forward-thinking as Apple wanted.

That doesn't mean you're stuck with 2013 silicon through 2017! And there's no reason whatsoever not to make a new motherboard that'll accept new Intel wafers each time they're refreshed. None.

If ASRock -- and Asus, and MSI, and Gigabyte -- can each release new mobos yearly for the enthusiast PC market, Apple can release one for Mac Pro users.

Apple only needed to be as committed as a reputable motherboard manufacturer -- no, less. They only needed to upgrade one mobo and GPU for one enclosure. They weren't and they didn't. It had nothing to do with sales volume. Really?

It's been three and a half years. Not enough sales volume? Three years' sales of Mac Pro are less than one year of Asus enthusiast boards?

Sales volume? That's a fail all around.

Labels: , , ,

posted by ruffin at 3/06/2017 08:26:00 AM
Friday, March 03, 2017

What I probably want is git update-index --skip-worktree [path]. Now that's screwy because it won't see updates either. What I really want is --dont-push-my-idiosyncratic-changes, but this'll have to do for now.

Undoing is apparently git update-index --no-skip-worktree [path]. Kinda feels like when I learned how to unset settings in VIm -- `:set nolist`.

Labels: ,

posted by ruffin at 3/03/2017 10:43:00 AM
Thursday, March 02, 2017

One last lesson in QuickBlox's JavaScript SDK before I call the client-side alpha I'm working on ready for testing... Unread counts.

One of the first things I do when someone logs in is pull back their active dialogs and then, on callback, get 10 messages for each of those dialogs. Then I have pretty much everything I need to display to the user as they switch from dialog to dialog.

As new messages come in to the active conversation (where "conversation" here is a synonym for a QuickBlox "dialog"), they're displayed and marked read. If they come into a backgrounded conversation, I put them into a separate array and add the count to the unread count for that conversation. If the user foregrounds that previously backgrounded conversation, I iterate through that "new but unread" array and let QB know they've been read now, because, at the very least, they've been displayed.

The snafu comes when you reload conversations who have unread messages in their ten most recent messages. That's the state you're in if new messages come into a backgrounded conversation, and the user never makes that conversation active.

By default, simply calling marks all the retrieved messages as read. Since I'm pulling them back before they're necessarily displayed, so we're not swapping conversations and being immediately greeted by a spinner (annoying and a poor user experience), I don't want them marked read yet.

That much is easy-ish. takes a parameters object, and you can send params.mark_as_read = 0 as one of the params. Now I do that when I get my list of messages for non-active conversations, and the server doesn't mark those read.

The problem now is splitting up which are read and which aren't when I load up the conversation. I want to take the unread ones and put them into the "new but unread" array I use for newly received messages. Then, if they make that conversation active, I can let the server know that now they should be marked read.

Here's an example unread message that returns. See if you can find the potential trouble.

    "_id": "mfn8211a99f2581a3b000000",
    "attachments": [],
    "chat_dialog_id": "mfnf0d2739de29f4db160077",
    "created_at": "2017-03-02T13:41:46Z",
    "date_sent": 1488462106,
    "delivered_ids": [
    "message": "test",
    "read_ids": [
    "recipient_id": 1115,
    "sender_id": 1114,
    "updated_at": "2017-03-02T13:41:47Z",
    "read": 1

That's right. read is 1, or "true". But look at delivered_ids (the message was received), recipient_id, and sender_id. Now compare to read_ids. See what I mean?

The sender has had the message marked read for them, but not the receiver. Yet I'm retrieving as the receiver here. My id is not in the read_ids list, yet read is still 1.

That means the message's read seems to equate to read_by_anyone_including_the_sender. That's not real useful.

I guess I'll just wrap this the way I talked about wrapping properties before, and add XReadByMe or readByAll or something similar.


Labels: , ,

posted by ruffin at 3/02/2017 09:33:00 AM

Support freedom
All posts can be accessed here:

Just the last year o' posts:

URLs I want to remember:
* Atari 2600 programming on your Mac
* joel on software (tip pt)
* Professional links: resume, github, paltry StackOverflow * Regular Expression Introduction (copy)
* The hex editor whose name I forget
* JSONLint to pretty-ify JSON
* Using CommonDialog in VB 6 * Free zip utils
* git repo mapped drive setup * Regex Tester
* Read the bits about the zone * Find column in sql server db by name
* Giant ASCII Textifier in Stick Figures (in Ivrit) * Quick intro to Javascript
* Don't [over-]sweat "micro-optimization" * Parsing str's in VB6
* .ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); (src) * Break on a Lenovo T430: Fn+Alt+B
email if ya gotta, RSS if ya wanna RSS, ¢ & Δ if you're keypadless

Powered by Blogger Curmudgeon Gamer badge
The postings on this site are my own and do not necessarily reflect the views of any employer, past or present, or other entity.