GFX::Monk Home

Posts tagged: "programming" - page 12

Understanding git submodules

I had to refer to this today, when I discovered (much to my surprise) that git submodules update does, for the most part, nothing.

You might expect it to update all my git submodules to the latest revision. Nope, I’m supposed to cd into each of those directories myself and run git pull myself.

The only hint that git update will do nothing of use is a single sentence in the help page, which mentions as part of the update command’s summary: “This will make the submodules HEAD be detached”. Which is a fairly unintelligible statement, even to someone who’s been using git for about a year now.

I can’t imagine when you would run git submodule update after the initial checkout - why doesn’t git submodule init just do update’s job (actually fetching the initial content), and then maybe we could have an update that actually pulls updates? I’d even be satisfied to have to use a flag, like --hard, --please or --come-on-old-chap-just-do-it-would-you

I’m pretty new to git’s submodules, and so far they just seem to take far too many manual steps (I don’t understand why they’re not fetched by a clone, for starters). I feel wrong saying so, but I miss svn:externals.

Tell me, how are things in the land of the other DVCS’s?


Update: Looks like my git is outdated, the newest version (1.6) allows a --merge or --rebase flag to update which sounds like it does what I want. Now I just need to sort out my mac’s package management :s

(view link)

OSX-style horizontal mouse scrolling for linux

OSX has this great feature where if you hold down SHIFT at the same time as using your mouse scroll wheel, it’ll scroll horizontally instead of vertically. If you don’t have a laptop, this is an immensely useful trick. Sadly, I couldn’t find any way to get this to happen on linux.

But now, thanks to some direction from stackoverflow, I finally figured out how to do it myself. The world of X11 input hackery is somewhat twisted and full of projects either abandoned or in disrepair, but I finally stumbled across the right set of tools.

If you’d like to get this (rather excellent) feature in linux, you will need the following:

  • Install the packages xbindkeys and xautomation: sudo apt-get install xbindkeys xautomation

  • Save the following file as ~/.xbindkeysrc.scm :

      ; bind shift + vertical scroll to horizontal scroll events
      (xbindkey '(shift "b:4") "xte 'mouseclick 6'")
      (xbindkey '(shift "b:5") "xte 'mouseclick 7'")
    
  • Use your favourite mechanism to ensure that the xbindkeys command is run at the beginning of your xsession (I added it to ubuntu’s “startup items” preference, but you can surely use init.d if you’re comfortable with that).

Autonose: continuous test runner for python's nosetests

Today I’ve put up the first “releaseable” version of autonose. Basically, it analyses your code’s imports, and determines exactly which tests rely on which code. So whenever you change a file, it’ll automatically run the tests that depend on the changed file (be it directly or transitively). Give it a go, and please let me know your feedback.

All you need do is:

$ easy_install autonose
$ cd [project_with_some_tests_in_it]
$ autonose

See the github project page for further information (and a screenshot).

minor metaprogramming

Can anyone tell me why ruby’s instance_variable_set would possibly require the name of a variable to start with an “@”, rather than simply assuming it? It’s a ruddy instance variable, after all…

I can find no decent alternative to python’s setattr in ruby, which surprises me.

Javascript: smells like lisp

I was just struck by how lisp-ish javascript is getting (not in the powerful code-as-data way, just the “screw builtin language features, lets just use more brackets for everything” way). Exemplified by this tiny sammy example code:

$.sammy(function() { with(this) {
  get('#/', function() { with(this) {
    $('#main').text('Welcome!');
  }});
}});

Entirely too much investigation into ruby's match operator

(how could a title like that not excite you! ;P)

So yesterday I had this weird regex issue in ruby. I wanted to get a regular expression containing a given string, but didn’t want to have to manually escape all the special characters. Regexp.escape to the rescue! It escapes all regex metacharacters in any given string, and returns it as a regex. In fact, the docs assure me:

For any string, Regexp.escape(str)=~str will be true.

But not so much in practice?

>> str = "123"            
=> "123"
>> Regexp.escape(str)=~str
TypeError: type mismatch: String given


So, problem one: Regexp.escape is broken. It returns not a Regexp, but a string. Oddly enough it also seems to escape spaces and other innocuous characters, but at least you get the right result if you pump it through Regexp.compile(). However, that wasn’t my only discovery.

I mentioned this to Matt, and he couldn’t make much sense of it either. He noticed that the type error is specific to strings - if you use a number it just returns false:

>> 123 =~ 'foo'
=> false

Seems a bit odd, really. Fixnum doesn’t implement =~, nor does Integer.

So I went doc spelunking. I found implementations for =~ in the following three important classes:

Regexp: regexp =~ str: do a regex match, as you might expect

String: str =~ obj: Call obj =~ str (i.e swap the order of your operands). Not mentioned in the docs but clearly apparent in the source (and experimentation): raise a TypeError if both arguments are strings. Without this, matching one string to another would very quickly run out of stack space.

Object: obj =~ other_obj: return false

So the Regexp implementation is fine. The String implementation is a little odd. I guess it’s there to allow people to write matching statements either way, but it seems like a dangerous (and confusing) habit to condone.

But the Object implementation? Why??? What possible reason could one have for doing a match operation against two objects, neither of which implement any matching behaviour? This has the painful side effect of giving every single object I inspect a “=~” method which does nothing. No wonder Object.new() has over 120 methods on it *.

For comparison, python’s object only has 12 methods / attributes. And they’re all special names, so there’s no pollution of regular names going on.

So there you go, two spoonfuls of broken in the one discovery!

(this is ruby 1.8.6, if that matters)

* I exaggerate, over 120 methods on object are just what you get in a rails app. Vanilla ruby only has 41 by my count. but it’s still completely unnecessary, and adds noise to inflate that number