Ruby feature: Regular Expression replace once

About a year ago, programmer Tony Arcieri posed a question on the Ruby language bug tracker:  Why was Thread.exclusive deprecated?

Among the answers to this question, Shyouhei Urabe’s one of the tersest feature descriptions yet: “we already have such thing, to some extent at least”:

  1. The pair of slashes are Regular Expression delimiters.
  2. A Regular Expression in Ruby allows String interpolation, just like the double-quoted String does. The #{} contains interpolated Ruby code.
  3. The modifier o at the end of the Regular Expression stands for “once”. So, the regex engine would keep track of this replacement, and do it just once.

The Malmo.rb named this expression (//o) the face-palm operator.

How to use very latest Bundler in Travis

TL;DR: When Bundler has fixes in master that you need, use the specific_install Rubygems plugin to install and use Bundler directly from a git branch. Example Travis YAML configuration excerpt:

  - gem update --system
  - gem install specific_install
  - gem specific_install
Picture: taken at Cambridge U Library. This is a CC0 free stock photo. But those are nice columns surrounding and wrapping the body of the page. Also: note the shadows of the supporting lines still visible in the finished book.

I will spend the rest of this post unpacking what the above means.

In Ruby, there is a package manager called Bundler. It’s continuously developed, and like all software, can have bugs.

When a Bundler bug gets fixed, the code changes are “merged to master branch”. Then we all wait for the next release. The workarounds are about sticking to an older, non-broken version: use the -v option to choose an exact release. Example: gem install bundler -v'1.13.7'

The Rubygems system does not have a way to install gems “from a Git source URI”, but it does have a plugin system. And luckily, one of the plugins available (but not on that page) is specific_install.

allows you to install an “edge” gem straight from its github repository, or install one from an arbitrary url

In order to work around the “we all wait for the next release” step, we can install the latest and greatest using this plugin.

The plugin’s has also aliased its specific_install action to git_install. The manual claims:

This alias is shorter and is more intention-revealing
of the gem's behavior.

Source: The above Travis configuration snippet comes from a PR to the releaf project.

A disciplined method to fix Rubocop TODOs

Here, a listicle of advice you never asked for!

A method to locate and fix linting errors in Rubocop one at a time:

  • choose a “cop” from the .rubocop_todo.yml file
  • remove the line which includes the .rubocop_todo.yml
  • rubocop --only Lint/IneffectiveAccessModifier
  • fix issues and test fixes with the --only invocation
  • rubocop --auto-gen-config to regenerate the .rubocop_todo.yml file
  • git checkout .rubocop.yml to add back include line
  • commit this change with the name of the “cop” used

I really really tried to use it at FakeFS.

Hold Elasticsearch back on 2.4 for Chewy on macOS

So, Elasticsearch 5.0.0 is out.

I’m using Chewy, a Ruby DSL gem that’s quite good. It’s not quite there yet with the deprecated Query APIs, (see Release Notes), so to keep using it you need to hold back to the Elasticsearch 2.4 series which is the last stable release. (Question about this, answered in the issue tracker.)

Smoky mountain top
Every upgrade is a damn climb. Yesterday was a good day. It was until 15:00 before I came upon package management issues.

Here are a couple of Homebrew invocations to stay on 2.4, with full data-loss, since the index version has been upgraded.

curl localhost:9200

The output for 5.0.0 is:

  "name" : "61mKC-n",
  "cluster_name" : "elasticsearch_olle",
  "cluster_uuid" : "EtOE3oHxQRSur5_qhRr-TQ",
  "version" : {
    "number" : "5.0.0",
    "build_hash" : "253032b",
    "build_date" : "2016-10-26T04:37:51.531Z",
    "build_snapshot" : false,
    "lucene_version" : "6.2.0"
  "tagline" : "You Know, for Search"

This is the version 5.0.0 that we can’t use with Chewy.

brew services status elasticsearch

If you don’t have one of those services running, you can skip a few steps.

brew services stop elasticsearch
brew unlink elasticsearch 

Now, with a clean slate, we can ask Homebrew to install a specific version (actually, a release series, “2.4”):

brew tap homebrew/versions
brew install elasticsearch24 
brew services start elasticsearch24

If you now run curl localhost:9200 you’ll may perhaps not see JSON ouput: if your index has been running on the 5.0.0, its lucene_index version would’ve been bumped, so that 2.4 can no longer read it.

The data files used by your Elasticsearch resides in /usr/local/var/elasticsearch. My node was called elasticsearch_olle and I decided to move all of its data out to a non-important folder on my harddrive:

mv /usr/local/var/elasticsearch/elasticsearch_olle ~/slask

After that, I could

brew services restart elasticsearch24

and then curl localhost:9200, to see the following 2.4 output:

  "name" : "Miss America",
  "cluster_name" : "elasticsearch_olle",
  "cluster_uuid" : "ym_Ovns4RHWqh-ZRcHWxcw",
  "version" : {
    "number" : "2.4.1",
    "build_hash" : "c67dc32e24162035d18d6fe1e952c4cbcbe79d16",
    "build_timestamp" : "2016-09-27T18:57:55Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.2"
  "tagline" : "You Know, for Search"


Photo credit: Kamil Szybalski

Ruby: Rubocop-friendly Hash pretty-printer

You’re desperate. Your legacy code-generation code outputs a Hash using hash#to_s. You’ve flouted many Rubocop rules to get to where you are. Suddenly, it gets too much. You search the Web for a pretty-print function that you want: a Rubocop-friendly Hash pretty-printer.

Empty-handed, you cough up blood, while a police car’s red-blue lights flicker in through the blinds of your run-down office.


With tired fingers, you type out something like:

Then, you faint, blessed sleep converges on you and envelopes you in a colorless void.

Photo credit: sethw

FYI: RAD (Ruby+Arduino) MIDI bounty

A quickie, I found this very interesting. I want to have happened, already: Ruby Arduino MIDI bounty.

Ain’t it cool? He is enticing you and me with some undefined hardware bounty. And pointing to GitHub as the place where you should upload your RAD-compatible MIDI library.

Note to self: RAD uses some language transformations to get where it is. Learn from them.

Copenhagen.rb meetup: Puppet and fringe activity

Juri presented the amazing Puppet framework for controlling servers. He controls about 20 servers with it.

Think of Puppet’s files as “setup Rakefiles for servers” which is version-controlled, monitored, and written in a very terse DSL. Seems slick. Juri might publish his nice slides, who knows.

While he was presenting, me and Lars SG were typing to each other, like kids in the back of the classroom. Quicksilver’s Large Type action was used a lot. It started when I noted he was working on the Counter example in Seaside, using a new Squeak. A fellow tourist in fringe-language-land!

We took quick detours into Io and CLisp (I had read about mapcar, and wanted to show what it was), and Lars turned out to be able to stomach even the most arcane crap. Perfect: a new special interest group in our Copenhagen Ruby Brigade. James Britt reports that this is a common Ruby programmer’s thing, and that it manifests itself in their meetups. See his link to fringedc for a picture of how to understand the “fringe” label.


RuPy 2007, European hacker meetup

Dear hackers: %w(Ruby Python).each {|lang| lang.discuss }

Thanks for a great weekend. “I’ll see you on the Internets” has never rung
more true than when I and Tomek and Krzysztof hurried out to a waiting taxi
(driven by a talkative bard-type, who talked “about nothing” with many words).

Now: go empty your camera, upload them somewhere, and tag the photos
rupy and rupy2007.

For those of you who just joined this narrative, I have just been to Poland,
to a technical conference. This was my second-ever visit to Poland.

The people I met were passionate, different, full of integrity, imaginative,
at play, and hospitable. The organizers and the attendees were excellent at
keeping a good, nice atmosphere. When something broke, or was postponed, the
moment was used to tell jokes, make friends, and have good times. Not a bad
word, ever. The way I want it to work, don’t change a thing.

As previously advertised on this braggy weblog, I was invited to speak at the
conference. This honour landed me my own room in a central hotel, where me and
the other speakers stayed.

Saturday morning me and Tomek went to the breakfast hall, which we managed to
find, even though the hotel was quite labyrinthine. We’d just sat down, when a
guy introduces himself like this: “I’m Adam, and the bus to the conference
leaves in 9 minutes.”

A yellow shortbus took us to Adam Mickiewicz university, a polytechnical
college on the outskirts of Poznan. I was in an expansive mood, and blabbered
on about Norse mythology being very hippy-like: Loki’s transformation to a
female horse, so he could give birth to Hel, goddess of hell, half babe, half
zombie. Among those that had to listen to this were Chris Arndt (Turbogears
speaker, from Germany) and Cloves X. Jr. (Rails freelancer, and author, from
Brazil-Canada-Dubai). Hands were shaken. Chris told us a bit about how his
local programming group’s shifted meeting format: no long presentations,
lightning-talks only, with follow-up discussions.

Krzysztof, a Warsaw friend of Tomek’s, was to do a talk about the Radiant CMS.
Program items were shuffled around a bit. Very agile, responding to change —
this let as many attendees as possible hear them. A side-effect was that we
wondered when our talks were scheduled. I got lucky, and my talk would wrap up
the first day’s Ruby track.

The rest of this rambling post will detail the talks, but I’d like to add that
the talks were only the starting point for the audience participation, in many
cases at least. You should go to conferences to interact, to do what’s
impossible online, and to learn from the audience if you speak. And the people
were just great: if you were there, and you talked to me, I probably lost your
email address (but hey, we use the Web for all those notes anyway), but I’d
love to be internet-pen-pals with all of you.

Chris A’s TurboGears talk showed step-by-step how to make “yet another
bookmark web app”, and this was good stuff. He took the time to detail how the
conventions-driven way of routing URLs with CherryPy. CherryPy is the
controller in the MVC of TurboGears. (Someone bitterly said: “CherryPy’s URL
dispatching sucks”, but at least I understood more about this. Thanks, Ola E
in Malmö for carefully explaining CherryPy to me.)

Python in embedded devices: This was the talk that my electrician would’ve
wanted to hear. The talk detailed what it was like to work with Python-enabled
hardware, that term meaning either “a small computer with flash memory instead
of a harddrive”, or “a little telephone-like unit the size of a matchstick
box” (from Telit). Inspiring to hear about off-the-shelf devices that you can
program. The term “home automation” stuck with me, a little like “family
atomics.” The downside to the Telit phone device was: their hardware Python
interpreter was at version (or something). “Audience: What are you
using it for? Speaker: I am not allowed to say.” NDAs, man.

PyPy (Python reimplemented in Python): “RPython stands for restricted Python,
and we’ve made it run up to 60 times as fast as CPython.” Full-on mad
professor style, the PyPy project has gone through an EU innovation
high-technology grant. They used the money on sprints with TDD and
pair-programming. One of the two speakers was unable to get to the conference,
but his colleague was ace.

An action-packed demo-filled talk, which among other things featured a
multi-player Bubble Bobble clone in JavaScript. And experimental Python
interpreters of all kinds. The idea is that by adding some new features to a
PyPy Python implementation (“can be done in 2 weeks”) they can optimize,
feature-add, or just experiment. Transparent proxies were an interesting style
of distributed computing, which almost removed the remote/local distinction.
The talk my head spinning with possibility, but Tomasz W. took me down to
Earth when he noted the RPython probably removed the dynamic stuff. “Otherwise
it would be too hard to generate C from it.” I’ll try and see what trade-offs
RPython does.

RLisp (Ruby-with-Lisp): Tomasz W. was very gracious, and let us early leavers
have a training run of his staggeringly geeky RLisp talk. The
implementer-inventor of this Lisp-with-Ruby, or Ruby-with-macros was a decent
presenter, and his material was very interesting. Tomasz writes a weblog, and a version of
RLisp is released, so you can go play with it. His audience was Ruby/Python
folks, so he kept the concept-count low, and explained things clearly. A warm,
nice person, and good at explaining his mindblowing ideas.

Presentation by delegation, Tomek called the second half of my talk. It was
meant to be a beginner’s introduction to making and serving Rubygems at home.
A step-by-step guide. I have to do a Companion Website for that, my material
needed meaty examples. And if I have a website for it, I won’t run out of
space. (Note to self: use the webgen gem for that.)

OK, all in all, this was a conference to remember, to keep friends from, and
to come back to.

Visited a gamefest: Nordic Game Jam 2007

Copy-party (or less aggressively, and perhaps more descriptively “demo-party”), that was the name of a weekend of mildly Dionysian digital festival here in Northern Europe during the late 80s and the 90s.

*Update:* Danish radio DR1’s show Harddisken has Frederik Berg Olsen’s radio programme about NGJ07. FBO had a tape recorder with him, and made a Gonzo radio reportage from the event, which’ll be broadcast (in Danish) tonight at 20:00. You can also download it, and hear it at your leisure.

Yesterday, I experienced the same kind of group exhilaration at Nordic Game Jam, a meetup of kindred souls from the Nordic area in Copenhagen’s IT university building. A whole weekend! 36 hours to design and make a computer game. No holds barred.

(I think the constraints of this Jam was about game design, not about technology.)

Fellow Copenhagener Frederik Berg Olsen was there, participating with the Snowscape team, as a game designer. I met his team-mates, and even though the rigors of completing a computer game in a limited time-span take their toll, they were a cheerful and kind lot. The puns at mid-afternoon on Sunday were quite… ripe. “RoboSnow! SnoboCop!”

My thoughts about what tools to bring to the next year’s Jam was:

* exotic hardware (dance mats, game joysticks with “force feedback”, light pistols, NES handcontrols — hm, should one make a NES game? Thorbiörn, whaddya say?)
* super-productive software kit to run said hardware (Pygame, some Ruby wrappers for SDL, perhaps, some Windows package — maybe HGE — to make games). Having tried the software before could be good. Does it run on my laptop? Does it do sound input? You know, trying to moderate the effects of Murphy’s Law.
* or, taking the “prevalent” route: Flash, with all bells and whistles. Or, even Javascript? In-browser, or not?
* or, tying in the Web in some way
* good ideas, games that you want to make

Yes, I say next year, ’cause I’m coming then. It looked like tons of fun.

Practical details that might be useful:

* Integration/build machine for Java projects. Run the Buildix live-CD Linux distribution.
* A wiki-wall of Post-its and so on, where Help Wanted, Stuff We Brought, Have You Seen My Blue Cable, etc, could be put up
* Pre-event setup Subversion repositories for everything — maybe Google Code? But, you need to be able to set the stuff up lightning-fast
* Perhaps having your own team’s tech-support/auxiliary guru to solve any crises. (But, hey, no crises, please.)

Update: I got Gosu with Ruby to work! It’s a delightful 2D-game framework. Cute!