RubyNation 2013 In Review

RubyNation 2013 is done! Outside of un-confs like BarCamp, it was the first conf I’ve presented at. I was nervous, so I kept practicing and smoothing the slides, and I think that helped a lot – everyone seemed to like the talk. Thanks again to everyone who came to hear it!

RubyNation was a smaller conference. Someone said they felt as though you could almost talk to every attendee, or at least recognize them all by face. It felt comfortable and familiar. But I think there was more to that than just being small – I think the organizers made some particular choices that made it that way.

First, rather than rows of chairs, they provided banquet-style round tables with about 10 chairs each. This is really good for getting people talking: you have a handful of neighbors, and you’re all facing each other. It’s much more social than 2 neighbors and the back of someone’s head. It does mean that half the table has to turn around to watch the talks, but in practice, it wasn’t a problem. Whatever extra floor space the round tables took up was worth it.

Second, rather than catering lunch, each conf organizer paired with a speaker to lead the way to a different nearby restaurant. Attendees got to pick which group they would go with. Splitting into so many groups meant there was a good chance you’d eat your lunch chatting with a speaker or organizer. It also meant you had much more choice over what to eat. (Remember RailsConf 2012, when they served pot pies every single day?)

Rails Girls DC was there in force. I’m not sure, but I think this was the first time RubyNation was paired with a Rails Girls DC training day. It was great to see so many people new to the community, discovering ruby and programming, and I think the variety of talks must have complemented the more-focused training day very well.

For a first-time speaker, it was a very welcoming, laid-back group – though, as Sandi Metz helpfully warned me ahead of time, they might not laugh too loudly at your jokes. If you’ve never given a talk at a conference, try starting with RubyNation.

Advertisements

I’m Speaking at RubyNation 2013!

This weekend, I’ll be giving a talk at RubyNation 2013, titled “Object-Functional Fusion in Ruby.”

While Ruby is a great object-oriented language, its functional aspects are a bit less-appreciated. But it’s no Haskell: if you try to go full-on-functional, you’ll run into headache and heartache. I want to talk about some ways to fuse the two approaches.

Come say hello!

Ruby Scrubbing JavaScript: Raise Those Curly Braces

Of the Programmer Holy Wars, “curly braces on the same line, or the next line?” is not as vitriolic as emacs/vim or tabs/spaces, but it’s up there.

(Personally, I don’t care. I’ve done years with each style. You get used to it.)

In JavaScript, it’s less of an issue, because, when you put curly braces on the next line, JavaScript will (sometimes) automatically insert semicolons into your code. It’s well-documented and discussed, and understandable; here’s a question about it on stackoverflow.

Yesterday I reviewed some old JavaScript (circa 2007) that our web designer Daniel rehabilitated, and this concern came up. Rather than hunt around manually for dangling curly braces, I wrote some ruby to find and fix them.

# fix-js-curies.rb
ARGV.each do |filename|
  src = File.read(filename)

  # This multi-line regex looks for any { that
  # comes after a \n, and any tabs or spaces,
  # and replaces it with a space and a {.
  new_src = src.gsub(/\n[ \t]*\{/m, ' {')

  if src == new_src
    puts filename
  else
    puts "#{filename} fixed!"
    File.open(filename, 'w') do |f|
      f.puts new_src
    end
  end
end

You can pass it any .js files as command-line arguments:

$ ruby fix-js-curlies.rb app/assets/*.js

Props to Daniel: when I ran my script, it didn’t actually find any, because he got them all ahead of me.

PSA: Connecticut Tech is Getting Exciting

New Haven Ruby is going strong, and New Haven JavaScript is heating up fast. We had a great turnout last night, with about 40 people at the Digital Surgeons office, and some great talks. Meet-ups are full of energy, introductions, and catching up with friends. And, obviously, tech talk.

broader New Haven tech community is emerging, combining NH.rb and NH.js with The Grove,  Independent Software, and now the A100 Developer Community.

The Greater Hartford ACM chapter is spinning up, and doing very well so far, hosting talks and tours of Connecticut technology centers. Hartford JavaScript is starting and Hartford Ruby is making a come-back (which I’m especially happy to see).

Connecticut hackers are doing some great things. Come out and join us!

Redder Pastures

What the hell happened? I mean, I don’t care for “I haven’t been blogging because…” posts either, but it’s been quiet here lately, hasn’t it?

The explanation comes in two parts:

After I announced I was releasing WordCram, I worked like mad on it. In my last post, the one announcing WordCram, I said “There’s still work to do, but that’s the fun part,” but I had no idea. And it’s not even a big library, or do anything useful! And there is certainly still work to do. I have a new, visceral appreciation for how much open source software developers give us. That’s the first part.

But all that stopped last April, when my employer began going through some – I guess “changes” is a safe enough word. Nevermind what they were. It got me thinking it was time to find a job I liked better. The job search is the second part of the explanation. I didn’t want another ordinary-business kind of job, but I didn’t know which direction to head in. After  sinking myself in some Processing.org dataviz, science, and Ruby, talking to a bunch of excellent people, and finding some luck, I got a spot on the SeeClickFix team, doing Ruby on Rails, and helping citizens improve their community.

Get a great job, working in a great language, making the world a little bit better:


I start in September, right before I start classes at Ruby Mendicant University. It’s been a busy spring and summer, and it’ll be a busy fall, too.

And at some point, I have some WordCram things to finish…

Where the Abstraction Leaks: JavaScript’s Fake Arrays

Ruby arrays have a nice feature: you can construct a new array with an integer N, and a block, which will be called N times, to fill up the array:

Array.new(5) { 'yo' }
# gives:
["yo", "yo", "yo", "yo", "yo"]

# Closures, too!
i = 0
Array.new(4) { i = i + 1 }
# gives:
[1, 2, 3, 4]

I tried to recreate this in JavaScript:

new Array(5, function() { return "drip"; });
// gives:
[5, function() {
    return "drip";
}]

Oops! I guess the Array constructor works differently in JavaScript. No worries, we can just call map on the new array.

new Array(5).map(function() { return "drip"; });
// gives:
[, , , , ]

…um, what? Shouldn’t that be ["drip", "drip", "drip", "drip", "drip"]? If I call new Array(3), I should get a brand new array, with 3 slots, all set to undefined; and I should be able to map over it, and fill up the array.

Let’s see what its elements are:

var array = new Array(5);
array[0]; // undefined, as expected
array[1]; // also undefined

So far, so good. What arguments are passed to the function?

function printAndDrip(arg) {
    print(arg);
    return "drip";
}
array.map(printAndDrip); // prints nothing, and returns [, , , , ]

It looks like the printAndDrip function is never being called, almost like the array has no contents.

Let’s try setting a value manually, then mapping:

array[2] = "hey there"; // [, , "hey there", , ], as expected
array.map(printAndDrip);
// prints "hey there", and returns [, , "drip", , ]

So, it only calls the function for values we’ve manually put there. Maybe map doesn’t call the function if the value of a slot is undefined? I know, I’m reaching here…

array = [1, undefined, 2];
array.map(printAndDrip);

/* prints:
1
undefined
2
then outputs:
["drip", "drip", "drip"]
*/

So it does call the function for undefined values! Then why didn’t it in our newly-created array?

This is when it hit me, and it’s a funny JavaScript fact that I always forget: JavaScript has fake arrays.

They’re actually closer to hash tables, whose keys are numbers. ["zero", "one"] is just syntax sugar: it creates an object with two properties, named 0 and 1; 0 points to “zero”, and 1 points to “one”.

// pretty much the same:
var arrayLiteral = ["zero", "one"];
var objectLiteral = { 0: "zero", 1: "one" };

Apparently, if you use the new Array(10) constructor, it creates an array with length 10, but with no named properties.

We can see the properties an object has with the hasOwnProperty method, so we can use that to test our hypothesis.

var emptyArray = new Array(10);
emptyArray.hasOwnProperty(0); // false
emptyArray.hasOwnProperty(1); // false

var fullArray = [1,2,3];
fullArray.hasOwnProperty(0); // true
fullArray.hasOwnProperty(1); // true
fullArray.hasOwnProperty(99); // false: gone past the end

So where does that leave us? Nowhere, really. At least I’m a little clearer about JavaScript’s fake arrays. Imitating Ruby’s Array constructor is pretty much out; it’s easy enough, though a bit unsatisfying, to hand-roll our own:

Array.filled = function(n, fn) {
    var array = [];
    while(n-- > 0) {
        array.push(fn());
    }
    return array;
}
Array.filled(5, function() { return "drip"; });
// gives:
["drip", "drip", "drip", "drip", "drip"]

Perhaps the folks working on the new JavaScript standards can put in a line-item about initializing Arrays with all the right numbered slots, and that’ll be unnecessary.

While writing this post, I used the JavaScript Shell 1.4 in FireFox 3.6.3 on Windows 7. I also redefined Array.prototype.toString to display JavaScript arrays the way you type them.

Accuracy and Precision: Not the Same

I often hear people mis-use the words accuracy and precision, but they mean different things.

To say I’m 117 years, 93 days, 4 hours, 17 minutes, and 48.249 seconds old is very precise, but it’s inaccurate (right now, anyway).  To say I’m in my thirties is accurate, but imprecise.  Precision is about level of detail, accuracy is about truthiness.

They make a wonderful pair, working pretty much orthogonally to each other.

Wikipedia has a nice analogy using a bulls-eye target.

My GoRuCo 2008 highlights

Aaron and I had a great time at GoRuCo 2008 last Saturday. Here are my highlights.

Bryan Helmkamp, Story-Driven Development

Bryan Helmkamp’s talk on SDD (slides, 1.6 MB PDF) reminded me of what Scott Hanselman calls “spec documents with teeth.” If I get it right, as you develop user stories, you use a standard format, and code parses your story file, and ties the text directly to functional tests you write. The stories aren’t executable themselves, but it brings them closer together.

Each story has a name, a description, and scenarios; the descriptions follow the format “As a …, I want to …, so that …”:

As a headhunter looking for Rails developers
I want to search for CVs with 8 years experience
So that I can make an exorbitant commission

The scenarios are different ways that story might play out. Each scenario has a description, which follows the format “Given … When … Then …”:

Scenario: Enough experience.
Given a CV with 9 years of Rails experience
When I search for qualified Rails candidates
Then I should find the CV
And I should realize the candidate is full of shit

Then code reads your story files, and uses the text following the keywords to connect to executable functional tests you write:

steps_for :cvs do
  Given "a CV with 3 years of Rails experience" do
    @cv = Developer.create!(:first_name => "Joe",
      :last_name => "Developer", :rails_exp => 3,
      :gender => "Male")
  end
end

steps_for :cvs do
  When "I search for qualified Rails candidates" do
    @results = Developer.find_qualified(8)
  end
end

The code that actually performs the test is just ActiveRecord. If you want to test the UI, there’s a DSL called Webrat that simulates the browser. It seems to live halfway between Watir and mechanize, and it doesn’t do javascript. It looks like this:

steps_for :cvs_with_ui do
  Given "a CV with 3 years of Rails experience" do
    visits new_developer_path
    fills_in "First name", :with => "Joe"
    fills_in "Last name", :with => "Developer"
    selects "4", :from => "Rails Experience"
    chooses "Male"
    clicks_button "Create"
  end
end

I’m curious about chooses "Male" — I don’t see how it connects that text with the drop-down it’s supposed to change, unless it looks at values for all drop-downs on the page. He gave a nice breakdown of the differences between Webrat and Selenium, and how SDD fits into an Agile team.

Giles Bowkett, Archaeopteryx

That’s ARK-ee-OP-ter-ix, or Arcx for short. Made by Giles (soft ‘g’) BOH-ket, or boh-KET, I wasn’t exactly sure which. It is, in his words, “a Ruby MIDI generator,” and “a system for auto-generating, self-modifying music.”

Giles had hands-down the most entertaining talk of the day. Instead of poring through each token of the code, he compared taking VC money (or “weasel-brained muppet fucker” money) to being an artist with a patron — as the programmer/artist, your job is to make stuff that makes your VC/patron look good. He showed some of Leonardo da Vinci’s designs that weren’t constructed until recently; that it took this long, he said, was a failure of da Vinci’s time. Similarly, staying within a VC’s idea of what’s possible is a failure of wasted passion and energy. Start-ups are so cheap now, you can ignore VCs — so follow your passion, create an open-source-enriched ecosystem around it, and make money by servicing the niche market you made. If your startup is great, you can say “my career is this thing”; if it’s mediocre, you can say “my career includes this thing”. Just remember that good artists ship.

Which brings us to Arcx, Giles’ idea for a crowd-interfacing, automatic music machine. Someone asked whether it was wise to name a new project after an extinct species, and Giles got all clever: archaeopteryx was either the last dinosaur or the first bird, and the project could be either the last DJ tool, or the first automatic music machine, played by the crowd. He played us some samples, and talked through the code just a bit, dropping hits about the CLOS-like structure of his code. As fun as his talk was, I would’ve liked to hear more music, and more about the lambda-passing and CLOS stuff.

He also pointed out the most interesting ruby book I’d never heard of, Practical Ruby Projects: Ideas for the Eclectic Programmer.

Chris Wanstrath, ParseTree

Out of all the talks, Chris’ was the one I’ll be using first. Lispers say “code is data,” and I can see why that’s so powerful — but I haven’t really tried it yet. ParseTree brings some of that coolness to ruby:

require 'ruby2ruby'

def to_ruby(&blk)
   blk.to_ruby
end

puts to_ruby { 1 + 1 }
puts to_ruby { |i| i == 42 }

def to_sexp(&blk)
   blk.to_sexp
end

puts to_sexp { 1 + 1 }
puts to_sexp { |i| i == 42 }

…which produces:

proc {
  (1 + 1)
}
proc { |i|
  (i == 42)
}
[:proc, nil, [:call,
   [:lit, 1], :+, [:array, [:lit, 1]]]]
[:proc, [:dasgn_curr, :i], [:call,
   [:dvar, :i], :==, [:array, [:lit, 42]]]]

Most of the examples he gave generated query syntax in a ruby-idiomatic way: say you have an ORM, and you want users to search for users like this:

old_cat_people = Users.select do |u|
   u.favorite_pet == "cat" && u.age > 100
end

How could you turn that into SQL? Call to_sexp on the query block (that’s “to S-expression“), and evaluate the abstract syntax tree it returns. Like this:

class Users
   def self.select(&query)
      query = query.to_sexp

      # Now, query looks like this:
      # [:proc,
      #    [:dasgn_curr, :u],
      #       [:and,
      #          [:call,
      #             [:call, [:dvar, :u], :favorite_pet],
      #             :==,
      #             [:array, [:str, "cat"]]],
      #          [:call,
      #             [:call, [:dvar, :u], :age],
      #             :>,
      #             [:array, [:lit, 100]]]]]

      # Time to evaluate the AST.
   end
end

Admittedly, it’s not that trivial, but that’s the gist of it — and I think the gem helps you with this. (Cue the smug Lispers: this stuff is natural in Lisp, the way passing anonymous functions blocks is in ruby.)

But here’s the interesting thing: we’re on our way to building .Net’s LINQ right into ruby. Remember, it stands for Language Integrated Query. LINQ is a big deal for .Net folks, because it’s handy. Microsoft put a lot of work into it, and it still needs its own new syntax. I think that’s a pretty clear example of the power of being able to see your own AST, and code off it.

Ryan Davis, Hurting Code for Fun and Profit

Ryan‘s talk was nominally about using tools like Heckle and Flog to beat the evil out of code, but my favorite part was his introspection-driven development. I know I’ll want to refer others to his slides and audio throughout my career.

Some of his tips for improving as a programmer:

  • Read. 1 technical book a month. Sites like c2.com — get close to the experts.
  • Focus. Only a few smart blogs: not zillions, not flame-prone. (Flame-retardant blogs?)
  • Grow. Learn 1 new language a year. Learn things outside of programming.
  • Learn from the pottery challenge story in Art & Fear: practice, a lot.

Ryan is also a fellow Dvorak typist, and pretty emphatic about it.

Johnson

Johnson is a ruby gem that executes JavaScript code. (It’s a successor to RKelly, which did the same thing.) I don’t know why I think this is so cool. Most people agreed the main use case for something like this is testing, but it seems to me there might be neater tricks to play. We’ll see how I feel after playing with it for a while.

GoRuCo 2009?

I’m definitely going next year — see you there.

Ruby’s other ternary operator

This may be a well-know Ruby trick, but I thought I’d share it anyway.

Ruby has the ternary operator:

a = true  ? 'a' : 'b' #=> "a"
b = false ? 'a' : 'b' #=> "b"

But it also has something else…

a = (true  && 'a') || b #=> "a"
b = (false && 'a') || b #=> "b"

All statements in Ruby return the value of the last expression evaluated, so true && 'a' returns ‘a’, and the ‘b’ is ignored (via boolean short-circuiting). false && 'a' evaluates to false, so Ruby moves on, and returns ‘b’.

 

This is a lot like the a ||= 'a' trick, which expands to a = a || 'a', giving the variable a default value, if it’s not already initialized.

If Ruby already has the ternary operator, why bother? Personally, I find this form more natural (which surprised me, after years of using the ternary operator in Java and C#). For some reason, it reads more like natural language to me.

user_name = (user.authenticated? && user.name) || 'guest'

Does anyone else see it?