KANPAI!

No Comments »

In Japan, things are a little more advanced. We know they’ve already got flying lazer cars and evil death robots who battle special teenagers with super transformation sequences, but they even have more boozing. See, the age of majority is lower then in the United States – it’s 20. In Japan, you get a whole year of extra boozin’ over your counterparts (although Australia is still two years ahead again).

Why am I bringing this up besides skyting at my friends from Freedomland? Well, because today, my favorite programming language, Ruby, can go out, smoke an entire pack of Lights, grope a paid adult entertainer, down an entire bottle of whiskey and then loudly throw up all over the street, because it turns Twenty today.

Now, I know you aren’t invited to the party (Because you’re not as cool as me and Ruby’s Daddy Matz doesn’t want your sort around) but Ruby is going HARD. It’s already updated it’s official age on its profile! OK, so there’s a decimal point in the wrong place but like YOU could write your age correctly after getting shitfaced on 2 bottles of sake and that really weird beer your sketchy friend drinks. Frankly, as long as Ruby doesn’t wake up next to Oracle, covered only in honey and fake fur, I think it’s doing pretty well.

Happy Birthday Ruby, Thanks Matz, and Rock on, Ruby Community! (Check out the SWEET gifts Ruby got At Ben Hoskings’ Blog)

(TL;DR for boring people –> Ruby version 2.0 is out AND it’s the 20th birthday of Ruby. Install, Code, Win.)

 
Share

A Reading from the Book of Ruby

2 Comments »

From the beginning of my career, I’ve been tending smaller and smaller. From consulting gig, to Government enterprise, to 300 person company, to smaller Government enterprise (never again) to a publishing company… Each one getting smaller in size, and feel. Agile, dynamic companies full of smart people is where it’s at.

I’ve also realised that I want to make things that matter to me, and one thing I’m really passionate about is developers. I *love* helping people and I love making cool shit, so being able to help people make cool shit is really exciting to me. I also think that people need time to think, to work and act… Doing things manually that aren’t valuable wastes the most valuable thing any given person has, their mind. I want to help free them.

Both of these put me on a trajectory to one single possible outcome, which I’ve chosen to put in interpretive danceeasily digestible image format:

Technically this is the Bridge

(This is San Francisco)

"THE" Bridge.

(I am here. Over my right shoulder is the Bridge)

8057709725_7c27f8e695

DEVELOPERS DEVELOPERS DEVELOPERS DEVELOPERS

I read from stdlib/json, line 23... (I am Ruby Developer Evangelist)

17 if you count our Consulting Miniature Schnauzer

(I am Employee Number 16 Here)

Which is good because it's cold.

(They even gave me a hoodie)

http://www.flickr.com/photos/antichrist/132623505/

(My job involves a lot of trips on these)

http://www.flickr.com/photos/cogocogo/6204578958/

(I’m also required to drink a lot of these. It’s a burden)

3265725073_66d6d3d7a6

4448466094_84eaa3cced

5442962755_4a87be8d7e

SeBlackRed

8291759460_307dba4bd3

(Sauce Labs do Selenium Testing in the Cloud) (Sauce Labs do Selenium Testing in the Cloud)

(It's fucking AWESOME)

(It’s fucking AWESOME)

3630920835_6a5f3a9b77

http://www.flickr.com/photos/chaunceydavis/3249393846 (You get Screenshots for every action and video of the entire test)

(And if you're not able to deploy development to the outside world, we provide Sauce Connect, an awesome VPN tunnelling solution)

(And if you’re not able to deploy development to the outside world, we provide Sauce Connect, an awesome VPN tunnelling solution)

http://www.flickr.com/photos/clango/3892009280/

http://www.flickr.com/photos/infomatique/8136256947

(Sauce Labs do Selenium Testing in the Cloud) (Sauce Labs runs our own cloud)

8328690534_6e588141bb_b

http://www.flickr.com/photos/nerdcoregirl/2614206246/

http://www.flickr.com/photos/skoett/4181589591/ (Instances run in seconds and last only as long as you need. Our CEO calls it Efervescent Computing)

(I am insanely excited to be able to work with such smart people on such a cool product)

(I am insanely excited to be able to work with such smart people on such a cool product)

My bailiwick is to make it better for Ruby developers to use the product, including improving the gems, writing better documentation and building the community. Plus, a unique opportunity to use my personality to insult people all over the world! If you want to offend your manager, disrupt your office and get kicked out of your favorite bar for getting shouty about whether RSpec shits all over Test::Unit (It does), let me know. Hell, even if you just want help with the Sauce Gem or tests from Ruby land, hit me up.

You can Find me on (T) or (E)

 
Share

Global Day of Code Retreat or Thoughtworks buys me Beer

1 Comment »

So I worked all weekend this week. I won’t get paid. I won’t even get a nod from my boss, although I was there for even longer for a standard work day. Jerks. Time to burn the office down. Get my stapler back.

OK, so they’re not jerks, and I wasn’t working at work. I was at Brisbane’s Global Day of Code Retreat, taking generous advantage of the Thoughtworks office’s fridge and wifi.

The idea is that you spend a day focusing on implementing the same thing over and over, so you can hone your professional skills. In the same way as a sculptor might practice straight lines over and over, we implemented Conway’s Game of Life using TDD techniques in 45 minutes. Every 45 minutes you had to delete your code and tests, debrief, and start again with a new constraint. Some of the constraints felt more annoying then educational, but on the whole I felt I got something out of every session. I also got to teach a couple of people something about TDD & RSpec, and I love helping others improve, so I got a kick out of being able to contribute like that.

I’m going to post how I found each session today, then mull over the others and post some observations a little bit later. I think it’s best to see how learning effects you in other contexts (like actually at work) before you jump into critiquing it, so I’m going to see how the next work week goes.

Session 1

Language: Ruby
Testing Framework: RSpec

This session just booted people off into implementing Conway’s life. I worked with a young Thoughtworker whose name eluded me, and we got about halfway into an implementation before time was up.

We spent the majority of this session just discussing what way to do things. I was a big fan of using a “Cell” object which maintained a list of its own neighbours, without directional information because it doesn’t matter. Doing it like this allows for arbitrary topologies (And I suspected that might be one of the constraints.)

Potentially tricky issues with this approach include implementing the tick for every cell at once(If you duplicate the cells, you have to duplicate the network and ensure you’ve duplicated every cell with its new state. If you mutate the network in place, each cell needs to know if it’s neighbours have ticked, and if so, what their state was last tick.

At the end of the session we had a discussion about what techniques people tried. Having a “Cell” object was quite popular (OO is like herpes, it spreads with contact), there was one “have a universe holding an array of cells” solution, and the one which I liked most, which was using the co-ordinates of the cells as a key for a hash of booleans, representing whether the cell is alive or dead. I really liked this… It’s unbounded (unlike an array in many languages) and *doesn’t* require a hojillion objects.

Session 2 – Ping Pong

Language: Ruby
Testing Framework: RSpec
Constraint: Each time you write a test, you ensure it tests properly, then you pass it to your pair and they have to do all the implementation. Then they write the next test, and you implement that

This session we decided to try the hash technique one of the groups suggested last time. I say”we decided” but actually mean “I decided”, because prevarication frustrates me, my partner had no strong opinions and I thought it sounded interesting so I made a snap decision.

The Ping Pong criteria is how I’d probably prefer to do pairing in the future, although usually it irks me (I need to be doing something and my “I’m not doing anything” behaviors usually irritate my pair). It meant that your tests had to be higher quality, and there was a defined place where you had to hand over to the other member of your pair — No long stints at the keyboard or just watching.

We didn’t get an implementation finished though, although I worked out how I’d like to derive neighbours. I proceeded to teach people a tiny bit of matrix math all day (more on that later)

Session 3 – Silent Ping Pong

Language: Ruby
Testing Framework: RSpec
Constraint: The same Ping Pong TDD as before, but this time you’re not allowed to talk

I paired again with a Thoughtworker this time, a gent from China called Hiyun (I hope, sorry if I’m wrong mate >.>). Wow. Dude was a shortcut pro. I learned a shittonne of RubyMine shortcuts and tricks I’d always wanted too but never devoted time to (Which is obviously my fault). It was really cool, probably my favorite session of the day.

We went back to the “Cell as self aware object” paradigm (drink). With the exception of a couple of inadequate tests, this session worked remarkably well. The inadequate tests required a lot of gesticulating. Once you’ve written something it’s hard to prove that the test is wrong rather then the code.

I think not being able to talk focused our attentions on communicating *only* our requirements through tests. There was no discussions of where you worked, what you thought of Test::Unit VS RSpec, why’s DHH’s hair like that; it was purely a “get shit done” event.

I think the most surprising thing was that we finished. It was almost like being unable to design architecture by consensus made one arise naturally out of requirements, which I am… skeptical of. I’m not sure how well our solution would have accommodated change, but maybe most software projects are simple enough that it doesn’t matter.

Session Four – No Primatives

Language: Ruby
Testing Framework: RSpec
Constraint: Rather then using native types to store results, cells and so on, use a wrapper class or object. No Arrays of cells, no Object.live? returns true

Oh god so hard. Getting away from primitives in Ruby is hard. Every time I wanted to wrap something I heard a tiny voice in my head stop talking about bees, games, cooking and Alice in Wonderland for a minute to scream “NEEdleSS ComPleXItY!“. All I wanted to do was use built in objects so I could rely on methods that Someone Else Has Tested™.

This session, we did something horrific. We decided that, if we weren’t going to use primitives, we’d use something as far removed as possible. Something so non-primative it’d make your eyes haemorrhage.

Files.

Yup. Files. To check if there was a cell at (4,5), you checked the directory ./data/4 for file 5.cell. If it existed, it was alive. Touch a location to make a cell alive, rm to delete it. We were planning to store the current generation number in the file to allow for ticking.

How’s that for non-primitives, bitches?

Session Five – Tests must pass in 3 minutes

Language: Java
Testing Framework: JUnit
Constraint: Once you start writing a test, you must write code to make it fail in three minutes or less. If you get to three minutes without it passing, you must revert all you changes and delete your test

The intent of this constraint, I believe, was to force you to test small amounts of functionality rather then huge sweeping changes. The idea is that small tests are good tests, and it’s tempting to write large tests that try to do too much. When they fail, you’re not actually sure why, and you lose much of the advantage of a full test suite.

My pair (Hi, Mike!) and I chose Java because it was our lingua franca (Scala was preferred but it’s quite hard to use a language without a dev environment, oddly enough). This may not have been the wisest choice, because of one simple truism:

Fuck me Java is Verbose!

It’s not just the punchline to the “what’s wrong with other people’s languages” joke. It was never really bought home to me just how verbose Java was until I had to spend so much time setting up each test. I’d just spent most of the day writing Ruby and now I’m having to give all my tests annotations and a typed, static method signature, and set up my variables types, and then set up and type the method and ensure to return the right sort of thing, and just making so much boilerplate it nearly made my eyes bleed (I propose we call this Stigjava.)

Even Mike, who writes Java for a living, was surprised. He said it bought Java’s verbosity into stark relief after a day of writing Ruby and Haskell. It forced us into doing true TDD because otherwise we simply couldn’t make a test that tested anythingin time. We had to implement the minimal amount every single test pass. Here’s how we had to test that we could get a list of neighbours for a cell:

  • Write a test to ensure that there is a “getNeighbours” method. Just that one exists. Pass it

  • Write a test to ensure the method returns an (empty) ArrayList. Pass it.
  • Write a test to ensure the method returns an ArrayList containing eight things
  • Run out of time because it took so long to learn how much code we could write at once

It was just astonishing. I’m not Java bashing (so passé), just really surprised. Writing the code to pass things, and even the tests, wash’t too hard, just getting to a point where we could do something took forever. And Mike is an IntelliJ wizard – Otherwise we’d have been screwed. He was making sweet combo love to the keyboard to bust out methods and variables and implement the signatures correctly and we were still fighting the clock.

Session Six – No Returns

Language: Ruby
Testing Framework: RSpec
Constraint: None of our methods could return values.

Woah. OK. Globalling it up. During this session I had a bit of an idea how to use events to generate a grid of neighbors, but didn’t implement it cleanly. Actually, this session was embarrassing because I forgot that Ruby is pass-by-reference, so resorted to using Globals. Don’t tell my mother. The solution wasn’t really productive, just because every time I manipulated the global objects I felt dirty and wanted to cry.

During this session, the pair using Haskell gave up on the constraint and just started trying to get it working at all. Globals were popular (at least we weren’t alone wallowing in filth) and only one group used callbacks. The idea I’d had was callback/eventing based, but wasn’t async, so obviously I need to do a bit more work about doing that kind of programming at need, rather then when forced.

Then, we had beer, a debrief and a powwow. Roughly half the room left straight away and the rest wanted to hang for a bit, which I always enjoy. I’m looking forward to the next one. I’m thinking this time, we use the presence of machines on a network as live cells….

 
Share

Avoiding worthless tests – a tip

No Comments »

A quick tip. It’s relatively easy to build a test, or an entire suite, and never actually ensure it gets run. Which makes all the effort that goes into it worthless AND gives you a false sense of security. It’s like having a photo of a security camera feed instead of the feed: “Of course everything’s safe, look!”

So, every time you create a new test file, assert that false == true. And run it. And make sure it fails.

Otherwise you’re wasting everyone’s time, especially your own.

 
Share

Finding & Enabling the web interface for Linksys ATAs

No Comments »

The Story

(If you just want the solution, check out the “Solution” section below)
My parents have a Linksys SPA-3102 ATA for making long distance and international calls (family in Victoria, daughter in Austin) because the idea of using a headset and a desktop program is weird and disturbing. Well, and it’s easier. Hi dad!

Recently the VOIP server (Privately operated) was broken into and used, no doubt, for one of those cheap phone cards or to power some sketchy “Hello this is Microsoft what is your credit card you have a virus in your cheese” scammer. The server admin reset the DNS binding, security and username policy so the ATA had to have its settings updated, which proved a challenge for my parent because the bloody thing wasn’t responding to its web interface.

So since I’m vising them at the moment I’ve been taking a look at the adapter and found that indeed, it’s not responding, and I’ve checked every device on the network to find out if it’s one of them (Which first involved finding the IP of the router because apparently 192.168.1.138 is a ‘proper’ address for a router. Which is security in the same way that hiding a key under the doormat is: You deserve to be broken into).

The problem was, I figured out, that its web interface was disabled (somehow). You can fix that, thankfully, with the magic of DTMF tones.


The Solution

It turns out these particular ATAs have a DTMF interface usable from any connected handset. So, as long as you’ve got a handset, you can dial numbers into it and get the information (and perform any configuration) you need.

Finding your ATA’s IP address

Enter the DTMF administration console by entering * * * * into the phone and waiting for the lovely British Robot Lady at the other end of the phone (I’m going to call her Estelle) to tell you you’ve entered the “Linksys Configuration Menu“.

Enter 1 1 0 # and Estelle will read out the device’s IP address.

Enabling the Web Interface

From the main menu (Just after Estelle welcomes you to the configuration system):

  1. Enter 7932
  2. Enter 1 #
  3. Wait to be asked to save
  4. Enter 1

You should now be able to head to the IP address quoted, on port 80 (the standard HTTP Port) to access the web interface, which is what I recommend for most tasks (If only for reasons of speed). Oh, and don’t forget you’ll probably find Advanced Admin mode more useful… Click on “Admin Login” then “Advanced on the right hand side of the web admin console’s header to enable it. And, just because it’s not *overly* clear, all the VOIP settings are under the “Voice” tab.

 
Share

Amazon finally realizes Australia has electricity, internet, geeks

1 Comment »

Amazon have (finally) released an Australian region for their web services. While I am not a jingoistic person, I’ve found that many businesses are. If your data isn’t “on-site” (In a data center they neither own nor control) they’re pretty scared. But move it off shore and suddenly it’s insecure and prone to foreign policy and you’re a Reckless Maniac!

I understand that having to comply with foreign policies regarding payments or accounting standards can be onerous, but most of the objections I’ve seen have to do with fear, or worse, imaginary fear about your customers fear. Although there’s something to be said for knowing your customers, assuming you know them is a bad way to provide things they might not even know they desperately want.

It’s really cool, though, that even people with a vague fear of offshore data (offshore money though, they’re cool with that *roll eyes*} can now take advantage of all of Amazon’s dynamic online services. Perhaps now is a good time to start a consulting software shop specializing in them.

You can read more about the move, and available services, in the AWS Blog post: Source

 
Share

Tip – Quickly Navigating to the Current Folder in RubyMine

No Comments »

I love IDEs. There. I said it. All Y’all can fuck about with VIM and TextMate until the cows come home. Give me a project navigator, tabs and windows to drag around, an entire environment I can commit to a repo. That’s where I’m most comfortable.

I use the fantastic RubyMine for Ruby projects. I’m often digging about in other areas for debugging and might not want to navigate all the way back to my project. But I don’t have too. All you have to do is click the little RubyMine icon (second from the left at the top in the picture) to be taken to your project’s root directory.

What are you hovering for? This isn't XKCD

RubyMine’s File Dialog

(Bonus tip: The folder icon, on the far right of the toolbar, shows hidden files and folders)

 
Share

JQueryUI Themes are fiddly (if you’re ignorant)

2 Comments »

JQueryUI has updated, and I want to take advantage of one of the new features (the response event for auto complete, fired after a search result is returned but before the menu is displayed), which means updating to the new version of JQuery… And re-creating my theme.

Now, “Luckily” I’m constrained in the colours I can use by another developer’s choices (I have to look pretty in their page, and was directed to use their colour scheme exactly), but that still left me with the prospect of trying to remember all the damn colour values, shades, effects and additional wunkery to apply, a prospect of slow revision over several hours, and not one I was looking forward too anymore then I’d look forward to being repeatedly slammed up against a large, moist, shaved yak covered in flaming mashed bananas. Bananas are fucking repulsive.

Reading through the CSS file produced last time, though, I don’t have too! Line 50 of jquery-ui-1.8.23.custom.css contains this gem:

1
To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,%20Arial,%20sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=444444&blahblahblah.......

That link takes you to the theme roller, with all your previous settings, ready to download suitable for the latest version of JQueryUI.

Fucking. Rad.

 
Share

Derping with Branches

1 Comment »

Because this just tripped me up, and I’d like to think that I’m not the only totally braindead developer out there.

Git is wonderful. You shouldn’t use any other source control. Even if your co-workers don’t get it (It’s because they’re stupid). Disk is cheap, you can afford to keep it all local. It’s fast, it’s flexible, it’s not actually that hard either.

But sometimes you might be trying to fetch a remote branch from your development server. You’ve checked documentation for the syntax and you know you can show your remote branches by issuing git branch -r, and the branch you want isn’t there.

What the Fuck?

Well, it’s actually embarassingly simple and not worth the 5 minutes you spent re-reading the documentation like a cargo-culting toddler whining about how unfair it is he has to eat dinner(“But it says this should wooooooorrrrrkkkkkkk!“).

git pull

.

That’s all. git pull won’t bring across any changes for the current branch (because there aren’t any) but it will bring across metadata changes, like new branches.

FFFFFFFUUUUUUUUUUUU………

 
Share

Asking Why and being a Cant

No Comments »

An interesting blog post by Nathaniel Boehm called Our Job is to Talk to People (An excellent title by the way, and the thing which originally drew me to the post) talks about asking “why” all the time. Why do you believe that? Why did you do that? Why do you need that functionality?

It’s an excellent question and core to providing software that’s actually good, although sometimes your users will be less thankful because of it. Habits and false beliefs are rampant in business, from gurus who won’t admit they got lucky to people whose jobs are to take the requirements from the customer and give them to the engineers who know they’re useless and are horribly defensive about it. Every company wants to think they’re different, and that often means they think their business processes have value.

Which. Is. Bullshit.

There is so much ceremony and good intention paperwork (From the good people at Road to Hell Pavers, Inc) bogging down most workforces, either through stubborn natures, unawareness of modern techniques and/or what software can bring them, and sometimes just because no-one has switched manual processes to automatic ones. Even geeks are prone to this: How many times have you not automated something because of an edge case you could simply detect and do manually, saving you 99% of the effort? So yes, UX (and software in general) can provide great stuff for people and make their lives better. The opportunity to do so is the most rewarding part of my job.

But there’s a negative version of the same Why principle. It’s Can’t, and can’t is very very common. Especially amongst incumbents. People LOVE to tell each other that things can’t be done, and what’s fucked up worse, we’ll listen to them! We let someone whose job we want to improve tell us that the thing we want to fix is a special little snowflake and couldn’t POSSIBLY be done by a soul-less machine.

Friends and family will find reasons to tear open your ideas by the arsehole, telling you that what you want to achieve isn’t possible. They’ll even dress it up in sensible sounding pronouncements about the time it’ll take to achieve, or how it’s going to cost too much. You’ll be wasting your time. You’ll be breaking the law. The most insidious reasons will be appeals to higher authorities, or totally fucking insulting. It’s illegal. If someone was going to do it BetterThenYou Pty Ltd would have already. Surely someone else provides it? That sounds like a lot of work. Sound familiar?

Not only are people not supporting you, some of them will be actively kicking you in the nuts, then pissing on you while you’re down. Half of those reasons (And I use the term in the same way airlines use the term food) are implying you’re an drooling, incapable fool, and the others that you have the creativity of a paper bag. These douchbags are supposed to be on your side! And unless your entire family are a pack of rabid naysaying hatebots desperate to see you fail (And you’re not a Rinehart, are you?) they’re not even trying to pull you down, they’re just falling prey to the same sort of canty malaise everyone seems to have. Some of it might be concern that you’ll fail and regret it and some of it, I’m sure, is jealousy that you’re persuing something you want to rather then sitting back in their cesspool of a life.

It may be apparent I hate being told I can’t do something.

Competitors also engage in canty behavior, but there it’s understandable. “You can’t open a bank out of a garage”/”You can’t offer virtual CRM instances”/”You can’t sell shoes online” are a two part combo of not wanting you to succeed, and being stuck in a rut (as discussed above). First they ignore you, then they mock you and all that. They want to reassure their own customers and themselves that they’re a better choice, and they you’ll probably go bankrupt and really, it’s better not to try, m’koy?

Fuck em. You can use great software and UX to make the world a better place, and make shit for yourself that cants tell you you, erm, can’t. So do it. Piss the cants off… You’ll get something awesome as a side effect.

 
Share