Baby’s First Ruby Script

  1. is like someone tried to reimplement CPAN with crayons and a dumpster.

  2. most of the Ruby community thinks an API dump is documentation. Some of them don’t even supply that.

  3. 90% of FAQs assume you’re using Rails. Maybe 95%.

  4. I got bad flashbacks to Pascal from having to put function definitions at the top. Yeah, whatever.

  5. “our {} is different” will trip me up for years.

  6. not being able to freely break lines mid-expression is annoying.

  7. googling for help always returns obsolete 10-year-old results (“thanks, pagerank!”).

  8. manual type conversion == stone knives and bearskins.

  9. ri is like someone tried to reimplement perldoc with chalk. In the rain.


I had a tiny project that had minimal dependencies. The Perl version flowed from my fingers like water, naturally, but the logic was trivial, and all it needed was a TOML parser and some random numbers, so it seemed like it would be easy to try out in Ruby. And I can even say something nice about the language: shuffle() and uniq() are core array methods.

A related script generates an improved Japanese Diceware ruleset using JMdict, but I haven’t found a full-featured romanization gem, and the advice about XML parsing is all over the map. Perl’s XML::Twig and its simplify() method have really spoiled me; I ended up having to mix Nokogiri::XML::Reader with Nori.parse, and then write my own force_arrays() function to emulate one of the most useful features of simplify(). The result is still only a crude approximation of what I can do with XML::Twig, but it suffices for this project.

While I’m complaining, the following gang-bang expression is not equivalent to the assignment version, which produces a sorted random unique subset of the array. Instead, you get the unsorted complement of the desired slice, unless the array was already unique, in which case Ruby blows chunks. This is, um, non-obvious.

words = words.uniq.shuffle.slice(0,7776).sort

On an unrelated note, I was amused to discover that the only useful PDF-generating gem still doesn’t support clipping paths, and while the authors claim it can easily be extended to support additional low-level PDF operators, that feature is not mentioned anywhere in the documentation or code…

Why play with Ruby in the first place? An old friend and on-again co-worker is a real zealot. Of course, our uses of scripting languages are very nearly orthogonal, to the point that many of the reasons I keep bouncing off of Ruby are things he never sees.

And, yes, I continue to be offended by Python’s use of indentation, although I’ll tolerate it at small scale to play with Ren’Py and CircuitPython. It’s heavily pushed on the Raspberry Pi as well, but at least there I can run Emacs and Perl, as Ghod intended.

Dear Amazon,

The Amazon Basics Computer Speakers are not well-shielded, and by that I mean they pick up local radio stations when the volume knob is at roughly 50%, and my hand acts as a convenient antenna when I adjust the knob. This defect is well-known, but buried by the mostly-positive reviews.

Apparently some people have had luck playing RMA roulette, but it’s pretty faint, so I think I’ll just ask Todd for some ferrite beads. Useful having a fully-stocked hardware department in your company. (and ohboy is it going to be fun to move that to the new building next month; some of his stuff isn’t going to fit into the elevator…)


Found some ferrite beads around the house, and adding them didn’t help. The radio signal was stronger this morning, enough that I could understand the ads, so back they go. Fortunately there’s an Amazon locker at the mall, so all I have to do is drop them off on the way to work.


Friday morning I dropped off the RMA and ordered these instead for $3 more. They’re the best-seller in the category, and it looks like I bought them just in time, since they’re out of stock now. With standard two-day Prime shipping, they were on my porch Saturday morning when I went out to feed the cats. They’re about twice the size of the Amazon Basics speakers, with much better sound, and no radio interference.

New Toys

My 7″ 1280x800 monitor got a bit flaky during the data center move, and while it survived, the screen quality will never be quite the same, so I picked up an Eyoyo 10″ 1920x1200. The blindingly bright blue power LED needed covering with gaffer tape, but the image quality is excellent, and it even has speakers. Works great with my Mac, but even though my Surface Pro 2 detects it and shows its resolution, for some reason it doesn’t send a video signal out to it via HDMI. I tried two different mini-Displayport adapters and a brand new high-end cable, so I suspect HDCP handshake issues.

[Update: there’s something a bit odd about the Eyoyo monitor; when I first plugged it into my new Raspberry Pi 3, it worked perfectly, including showing the splash screen, but ever since, it only works if I force-select a video mode. Still works fine with the Mac, but it simply cannot auto-sync with the Pi, or show anything from the Surface Pro 2, which makes it “less than versatile”]

While setting up my cube in the new building (which included swapping the desk pieces around and adding a partial roof), I decided to ditch the crufty old USB2 hub I was using in favor of an Anker 10-port USB3 with fast charging support. Mostly because the right-hand USB port on my MacBook Pro went out a while back. Maybe after the holidays I’ll send it in for service; I think the AppleCare runs until February.

Those were easily justified purchases, but in the nearly-pure toy department, I picked up a TrueRNG3 USB hardware random number generator. Automatically supported in Linux, works on a Mac if you manually send the output to /dev/random, and they have a Windows driver. Sadly, while OpenBSD 6.2 supports several USB HRNG, it looks like the TrueRNG isn’t one of them. Yet.

I don’t have dieharder test output from it at the moment, because it only delivers 50 KB/s of random bits, but ent really likes its output. The vendor claims to pass the dieharder tests, but doesn’t say how long it took to generate enough samples (some of the tests consume a lot of bytes).

Why am I trying to improve the quality of my random numbers? Because I’ve been playing with random passphrase generation again, using a rule-based generator that lets me feed in a variety of patterns and dictionaries, for Diceware-style generation with calculated entropy. For instance, one script generates an improved romanized Japanese diceware list, based on the word-frequency rankings in JMdict, and I can do side-by-side comparisons between different lists to see how easy the results are to remember. Side note: the EFF wordlists are a nice improvement on the original English 5-dice lists, and they’ve got two nice 4-dice lists as well, with interesting properties.

For real fun, I set my generator up to allow mixing multiple rulesets, which is a relatively minor increase in entropy, but definitely more entertaining (especially if you include the Lord Of The Rings ruleset…).

And it also let me prototype an updated syllable-based system using polyhedral dice. Cut out and save!

|     Random Passphrase Generator      |      Digits, Specials, Uppercase     |
|                                      |                                      |
|  1  2  3  4  5  6  7  8  9 10 11 12  |     1  2  3  4  5  6  7  8  9  0     |
| -----------------------------------  |     @  #  %  $  !  |  &  _  ,  :     |
|  s  v  p  h  f  k  r  t  j  m  w  b  |     A  B  C  K  N  Q  T  X  Y  Z     |
|                                      |     +  -  *  /                       |
|       1   2   3   4   5   6   7   8  |                                      |
|   +--------------------------------  |     d12 * d8 * d6 = 9.17 bits        |
| 1 | eth  id  ol  eg  od  az  it  el  |     var/op/digit = 8.64 bits         |
| 2 |  ug  og  an  as  on  ar  is  al  |     d10 = 3.32 bits                  |
| 3 | ath  ay  ot  iz  us  os   a   e  |     d4 = 2 bits                      |
| 4 |  et  il   u  ed  ig  uz oth   o  |                                      |
| 5 |  oy  ul  ag  en  un  oz  or  es  |     10 syl ~ 14-char random ASCII    |
| 6 |  ad  ez ith  ut   i  ud  in  at  |     12 syl > 16-char random ASCII    |

(this table shouldn’t wrap on most screens, but for some reason it does in Chromium on my shiny new Raspberry Pi at 1920x1200, unless I zoom the font size to 80%, 110%, or 200%; some odd scaling in the version of Bootstrap I’m using, I guess)

Most people never find the old Diceware tables for generating syllables, special characters, etc. They’re buried in the original mailing-list post for Diceware, and aren’t referenced in the current HTML pages. Most of them aren’t particularly useful, but if your password policies require some combination of upper-case, special characters, and digits, they’re better than just appending “A1!” to every password. My var/op/digit rules above exist for the same reason; I find it pretty easy to remember “Z/4” or “X+2”.

Abort, Retry, Ignore

I think I like “Invalid Frn.” best.


What could possibly go wrong?

Scott reports, you decide:

My gaming laptop started getting really flaky (first one USB port went, then two more, then the wireless and HDMI out, etc) a couple of weeks ago, so I ordered a brand new Alienware 15. It arrived on Wednesday and I started the process of downloading and installing Windows updates, Steam, Fallout 4, etc. The only problem was that it kept going to sleep during the downloads. No matter what I changed in the power settings, it kept going to sleep.

As it turns out, some idiot at Dell thought it would be a good idea to install and enable by default eyeball tracking software that puts the laptop to sleep if you look away from it for “too long”. (Where “too long” is no more than a minute or two.) Needless to say, that package has been removed from the machine.

There’s a short story just begging to be written here, where an enterprising hacker releases ransomware that, instead of asking for bitcoins, hijacks the eye-tracking software and demands that you watch ads all day. Or just shouts “show your tits!” whenever it detects a college girl using a laptop.

Dear GNU Emacs,

Why did you remove count-lines-region and make the only option count-lines-page? How is counting Control-L-delimited “pages” useful as a default behavior?

Worse, the only way to get line-count from a region is now count-words-region, but that takes extra keystrokes to avoid invoking count-words. (yes, I know there are keyboard shortcuts; there are lots of keyboard shortcuts. I’ve never trusted them to be stable)

So, more workarounds in my .emacs file to turn Emacs back into a text editor. 😡 💩 🔥

Samsung T3 500GB USB3 SSD

My work MacBook Pro (mid-2014 edition) only has 512GB of storage. I had tried to order it fully loaded, but somebody upstream fainted from shock, despite the fact that my previous machine was nearly 8 years old.

I’ve got to do a lot of tinkering with VMware and Docker images for working out the IT infrastructure in our new building, and there’s just not enough space for it all on the internal drive. And since Apple solders everything to the motherboard these days, there’s no way to upgrade without replacing the machine. Browsing for small external SSDs, the Samsung T3 seems to be well-rated.

The only problem I can report so far is that it draws more power than the left USB3 port on my Mac can reliably supply. Moving it to the right port got rid of the eject/remount every 2-3 minutes. I’m not using their encryption, because I don’t need it; also, there are some reports of the supplied Mac software being flaky, and I had a few bad experiences with the way the equivalent WD driver works.

By the way, if you use Docker on a Mac, it will graduallyrapidly fill your disk unless you periodically rebuild the Docker.qcow2 file (works best if you supply the names of the images you don’t want deleted). A fix is reported to be in the works.

Mac Bash-ing

If you drag URLs around on a Mac, you get .webloc files. If you drag text around (successfully…), you get .textClipping files. Getting data back out of them can be annoying; some applications treat them as attachments, and most insist on grabbing the rich-text version of a clipping rather than the plain text.

webloc () {
  /usr/libexec/PlistBuddy -c 'print URL' "$1"
clipping () {
  DeRez -noResolve -only utf8 "$1" |
    perl -e 'while (<>) {
      next unless s/^\s+\$"([0-9A-F ]+)".*$/$1/;
      tr/ //d;
      $x.= $_;
    print pack("H*",$x),"\n"'

“Need a clue, take a clue,
 got a clue, leave a clue”