Now on Posterous
I recently started using my posterous account for shorter blurbs. Have a look at http://trotter.posterous.com if want to see what I’ve been playing with lately. (Hint: newflow, cuke-talker, and some random Rails bugs).
Ruby Style attr_reader and attr_writer in JavaScript
So I’m playing around with a JavaScript URI parsing library right now, and decided it would be fun to implement Ruby’s attr_reader and attr_writer in JavaScript. It turned out to be pretty simple, with the only tricky part being dealing with the capturing the current value of a variable in my closure.
Check it out:
var attrReader, attrWriter, private;
private = {};
attrReader = function () {
var i, anon, methods;
methods = arguments;
for (i = 0; i < methods.length; i += 1) {
anon = function () {
var j = i;
that[methods[j]] = function () {
return private[methods[j]];
};
}();
}
};
attrWriter = function () {
var i, anon, methods;
methods = arguments;
for (i = 0; i < methods.length; i += 1) {
anon = function () {
var name, method;
name = methods[i]
method = "set" + name[0].toUpperCase() + name.substring(1, name.length);
that[method] = function (val) {
private[name] = val;
};
}();
}
};
attrReader("scheme", "host", "userInfo", "port", "path",
"queryString", "fragment");
attrWriter("scheme", "host", "userInfo", "port", "path",
"queryString", "fragment");
As a word of warning, this whole thing is probably terribly slow. Oh well, it’s really just for fun.
JSLint and Screw.Unit
I’ve been working on a new JavaScript library lately and I like using JSLint to ensure my code is good. Unfortunately, JSLint will go nuts when you run it over a Screw.Unit test file. Thankfully, the fix is as simple as adding an extern declaration at the top. The extern tells JSLint that the following variable names are defined outside the current file. For Screw.Unit, the following extern declaration worked:
/*extern Screw, describe, it, expect, equal, before */
Custom ArgumentMatchers in rSpec
Ok, so you know the stuff you pass into #with when doing stubs and mocks in
rSpec? Those are called ArgumentMatchers. Most of the time you’re writing
code like obj.should_receive(:blah).with('a string'), but you can get fancier
and use rSpec’s built in ArgumentMatchers to do other nice things like
obj.should_receive(:blah).with(hash_including(:key => 'val')), which will
match a call like obj.blah(:foo => 'bar', :key => 'val').
This is neat and all, but rSpec’s ArgumentMatchers don’t always go as far as
you’d like. In particular, there’s a hash_including, but no array_including.
In the rest of this post, I’m going to show you how to write your own
expectations, using array_including as an example. It turns out to be
surprisingly simple.
So first, a word of warning, in rSpec 1.1.12 ArgumentMatchers are called
ArgumentConstraints. Replace all occurrences of ArgumentMatchers below with
ArgumentConstraints, unless you’re on rSpec edge.
With that disclaimer out of the way, open your spec_helper.rb, where we’re
going to add an ArrayIncludingMatcher to the Spec::Mocks::ArgumentMatchers
namespace. We will define an initialize method to take and store the expected
value, and == method to compare against the actual value, and a description
method to print out a handy description when the test fails.
module Spec
module Mocks
module ArgumentMatchers
class ArrayIncludingMatcher
# We'll allow an array of arguments to be passed in, so that you can do
# things like obj.should_receive(:blah).with(array_including('a', 'b'))
def initialize(*expected)
@expected = expected
end
# actual is the array (hopefully) passed to the method by the user.
# We'll check that it includes all the expected values, and return false
# if it doesn't or if we blow up because #include? is not defined.
def ==(actual)
@expected.each do |expected|
return false unless actual.include?(expected)
end
true
rescue NoMethodError => ex
return false
end
def description
"array_including(#{@expected.join(', ')})"
end
end
# array_including is a helpful wrapper that allows us to actually type
# #with(array_including(...)) instead of ArrayIncludingMatcher.new(...)
def array_including(*args)
ArrayIncludingMatcher.new(*args)
end
end
end
end
Note that we also defined an array_including method as the readable wrapper.
For symettry’s sake, we should also define ArrayNotIncludingMatcher, which
I’ve included in the following gist. Feel free to copy this matcher, but I’d
love to see you guys creating your own. Leave links to gists in the comments if
you come up with anything fun!
Update: I had to remove the embedded gist because it was hanging the page when github was down. Check out the link if you can: http://gist.github.com/62943.js.
Data Urls and document.domain
Well this is a bummer. It turns out that all data urls share a common domain of ””. This is a problem in HTML5, because access to sqlite databases is based on the document.domain (This is true in safari at least). Therefore, all data urls will share a common sqlite db environment, meaning that a data url from Google,could look in the database created by a Yahoo data url, given that they were able to guess the name of the database. Since I see data urls as a better way to do offline web apps than google gears, this is a problem that pains me. Does anyone know if there is a solution?
My main thought on how to fix this would be to require the domain for any data url that is a target of an link be set to the domain of the linker. The same would go for any data url that is loaded via a src=””, but this shouldn’t matter as all scripts use the document domain and not their own domain for security purposes. In cases where this is no linker, data urls get their domain set to an md5 hash of their data. Anyone see any problems with this solution?
If you don’t know what data urls are, check out my previous post.
Data Urls Are Fun!
Lately I’ve been playing with data urls in an effort to use them as an alternative way to build iPhone apps. W. Clawpaws wrote an interesting post on this a year ago, but it seems that not much has been done since. If it’s possible, I plan to have a simple library built by end of year that will allow you to write data url apps that connect to a central server when available. Basically, it’ll make the persistence and speed arguments for writing native apps null and void.
Anyway, enough of what I plan to do and more about actual data urls. “Data urls”http://en.wikipedia.org/wiki/Data_URI_scheme allow you to store a single image, some javascript, or even an entire web page in a url. The browser will then render that information as if it were pulling it from a normal http:// url. So they will increase the initial payload of your web page, but result in faster interactions once the page is loaded.
Data urls have a format of
data:[<MIME-type>][;charset="<encoding>"][;base64],<data>
So if you see something like data:text/html;base64,PGh0bWw+, you’re looking at a data url. To see one in action, click the link below and have a look at the url in your navigation bar.
Check back in the near future for progress on the iPhone idea. In the meantime, enjoy playing with data urls.
iPhone on Rails: The Presentation
Last night’s presentation went pretty well. I gave a fairly high level (except for the XCode part) overview of developing web and native apps for the iPhone. I hope to spruce this one up based on the questions asked during the talk last night and give it again some place else. Anyway, slides are below.
iPhone on Rails
I’m a little late to this party, but I’m speaking at philly.rb tonight. The talk is about making rails backed iPhone apps, both web and native. It should be a raucous good time, so come on over if you’re near Philly.
As an aside, there’s a chance that this will be taped or that I’ll actually upload my slides for once. That said, if you miss the talk, you’re probably shit out of luck for my valuable knowledge.
iPhone Resources
I’m sure you’ve heard by now that the iPhone NDA has been lifted. This is great news for those of us that pretend to be iPhone developers, because we’re going to start seeing a lot more resources at our fingertips.
I’m going to start keeping a moderated page of iPhone development resources including links to blog posts, books, and maybe even podcasts. If you see any blog posts (I’m sure there’ll be tons in the next few days). Let me know and I’ll add them to the list.
Mocking Screw-Unit Part Deux
I wrote earlier about how Topper mocked out the dom for screw-unit testing. Taking his lead, I started playing with screw-unit and adding some mocking and stubbing in the rspec way. It’s not quite release worthy, but it’s on github now and I think it’s nearly usable. Basically, it lets you do things like this:
user = {login: 'bob'};
Screw.Stub.stub(user, 'login').andReturn('nancy');
user.login; // => 'nancy'
Screw.Stub.reset(); // Called automatically after each spec
user.login; // => 'bob'
// Will throw a spec failure if user.email() is never called.
Screw.stub.shouldReceive(user, 'email');
Obviously shouldReceive is not quite complete. It’s missing with(), numberOfTimes(), and other things. Still, it’s good enough that others can start iterating on the model I’ve laid down. As I said earlier, my fork of screw-unit is available on github now, so have a look and feel free to leave questions in the comments.
git-bisect Is Your New Best Friend
To anyone not using git, jump to the bottom of the post then come back up.
Update: I’ve got an even faster method at the bottom now. Skip down there if you already know the basics of git-bisect.
Ok, now let’s move on to the cool shit, git-bisect. Git-bisect helps you figure out exactly what code change broke a feature in your app, even when that code change was made months ago. It works by assisting you in a binary tree search through your commits, pausing at each one so that you can run a test and mark that commit as good or bad. This can remarkably decrease the amount of time you spend trying to figure out what is causing a new bug, because you quickly can find the exact code change that introduced it.
To use git-bisect, you first need a good test to run. Though you could do a manual test like loading a page in your browser and verifying that things look correct, you will be much happier if you write an automated test that you can run for each commit. Since I usually live in Ruby land, I’m fairly partial to TestUnit and rSpec for my automated tests. If you’re in iPhone land, I strongly recommend using google-toolbox-for-mac.
With automated test in hand, you can kick off git-bisect with git bisect start. You then mark your current commit as bad using git bisect bad. You then checkout a known good commit using git checkout commit_hash. Run your test and mark it as good when it passes using git bisect good. At this point, git-bisect takes over and starts moving you through commit after commit. At each stop, you run your test and then mark the commit using either git bisect bad or git bisect good. At the end, git-bisect will tell you which commit first caused your error. You can then use git diff commit_hash to see what was changed in that commit. When you’re done, you run git bisect reset to set everything back to normal.
A typical git-bisect session looks somewhat like this:
(master) $ git bisect start
(master|BISECTING) $ git bisect bad
(master|BISECTING) $ git checkout eb5eecbb8fc4e2a964e8d2043d8b95f4eb7b563a
HEAD is now at eb5eecb... Add MainViewController
... run test which passes ...
(eb5eecb...|BISECTING) $ git bisect good
Bisecting: 3 revisions left to test after this
[d82c1595b6363484fe0d7f60f9ffa096d777bf17] First CompsView test
... run test which fails ...
(d82c159...|BISECTING) $ git bisect bad
Bisecting: 1 revisions left to test after this
[93af33167019fa039f5372dff602a76cbcbc99bb] Add first integration test
... run test which passes ...
(93af331...|BISECTING) $ git bisect good
Bisecting: 0 revisions left to test after this
[4f12091a287c363737ceb650df46196e5008d3f2] Add Comps target
... run test which fails ...
(4f12091...|BISECTING) $ git bisect bad
4f12091a287c363737ceb650df46196e5008d3f2 is first bad commit
commit 4f12091a287c363737ceb650df46196e5008d3f2
Author: Trotter Cashion <cashion@example.com>
Date: Tue Sep 23 20:18:09 2008 -0400
Add Comps target
:000000 100644 0000000000000000000000000000000000000000 789bf7877c6059a7f3ac8cb2b53fdb2c903e58ff A Comps-Info.plist
:040000 040000 d260571a48328d4a575a7395cd6ece3d651a93ac a622a23fdb80c915eaba49d1d53f7bf0dbf44a70 M ShootAndSpeak.xcodeproj
... Figure out what's wrong ...
(4f12091...|BISECTING) $ git bisect reset
Switched to branch "master"
I hope you learn to use and love git-bisect. It’s really helped me when trying to find the cause of nasty bugs that seemingly came out of nowhere.
Update
The above is too much work. While searching the net, I found something even easier and faster. You can start git-bisect with the commit hashes like so git bisect start bad_commit good_commit. Even better, you can then tell git-bisect to run the tests itself… this is where things get awesome: git bisect run some_test. It’ll iterate through your commits until it finds the bad one. Checkout the sample session below.
/tmp/fake(master) $ git bisect start 68d5ab7a61a871fd097d8820e248cfd168395e4e 20cbc038973d6c78805bc8bfc3d187c2b537f183
Bisecting: 1 revisions left to test after this
[3da37ed0ee87c9129a61142ecefef17ab0de7f0f] Test works
/tmp/fake(3da37ed...|BISECTING) $ git bisect run testrb test/unit/some_test.rb -n test_truth
running testrb test/unit/some_test.rb -n test_truth
Loaded suite some_test.rb
Started
.
Finished in 0.000338 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
Bisecting: 0 revisions left to test after this
[765d7e5c4eba730078907fc00121b8b35ada64b0] Test fails
running testrb test/unit/some_test.rb -n test_truth
Loaded suite some_test.rb
Started
F
Finished in 0.009607 seconds.
1) Failure:
test_truth(ThisTest) [./test/unit/some_test.rb:5]:
<false> is not true.
1 tests, 1 assertions, 1 failures, 0 errors
765d7e5c4eba730078907fc00121b8b35ada64b0 is first bad commit
commit 765d7e5c4eba730078907fc00121b8b35ada64b0
Author: Trotter Cashion <cashion@example.com>
Date: Sun Sep 28 13:13:09 2008 -0400
Test fails
:040000 040000 167dd04f2b4101ea256a7a6525859bc03e5433d3 0b062d4b5b03e7ac51ac4050fc7397c8983a2f13 M test
bisect run success
/tmp/fake(765d7e5...|BISECTING) $
As you can see above, I’m using ruby for this set of tests. My preferred method is to have git-bisect run testrb (or spec) and specify a single test for it to execute. This ensures that everything runs quite quickly.
Land Here!
If you jumped here from the top, I regret to inform you that this post will make you very sad. Turn back now before you’re stuck improving your life by installing git. Once you’ve installed git, go check out Peepcode. They’ve got a really good screencast and pdf that explain git excellently.
Mocking Screw-Unit
I’m big on tests. Unit testing helps me clarify my thinking on problems and ensure that my code works well. When writing tests, it’s essential to have a good mocking framework to separate the things you are testing from the things you are not. In Ruby, I like using flexmock for Test::Unit and rSpec’s built in mocking framework when using it. In Javascript though, screw-unit doesn’t really come with a way to mock by default. (As an aside, screw-unit totally rocks for testing js.)
Thankfully, my coworker Topper (who’s a kickass dev, btw), has been playing around with adding mocking to screw-unit. He’s got a fork on github, docs at the previous link, and a quick example blog post. Click through and check this shit out, cause it’s hot.
Floating Pain
Topper mentioned a tweet he saw to me in which someone asked why (4.6 * 100).to_i #=> 459. Though this seems like a ruby bug, it’s really just one of the annoying things you hit with rounding errors and floats. At issue is that #to_i floors the float, instead of rounding it. Since the value may be approximated at 459.999999, the #to_i floors it to 459. To have things work like you’d expect, use #round when converting Float to Fixnum. See below for some code examples:
4.6.to_i # => 4 4.6.round # => 5 (4.6 * 100).to_i # => 459 (4.6 * 100).round # => 460
How I Got Started Programming
Paul says I’ve got to do this, and I don’t want to let him down. Giles tagged him first, so you should probably read his too.
How old were you when you started programming?
In third grade (when I was 8) I started started taking super nerd math classes with other super nerds. As part of those classes, they had us programming a turtle to draw things on the screen. Logo) was totally awesome and had me hooked on the magic of programming.
How did you get started programming?
After Logo, my dad (he was a CTO at the time) bought me Visual Studio and a few books on Visual Basic. It was lots of “Teach Yourself X in X days”, and I ran through VB, C++, and a little Delphi. Naturally, those books didn’t teach me to actually be good, though I did figure out how to make a few small games that I could play.
My dad was a CTO at an investment bank, which is the kind of place that treats a CTO like crap. I didn’t want to be the guy that got shat on, so in high school I dropped programming and started learning businessy things. I even picked my college based on the strength of its business school. Once I showed up, I realized that I didn’t like anyone at the business school, that philosophy was fun, and that math/econ could make me money. I promptly switched my major.
After college, I went to work at a job that I ended up hating, quit it, took a few months to figure out my life, and realized that I really loved programming. Thankfully I got lucky and read a blog post that tipped me to the beta book of AWDWR, which taught me a lot about real programming. I consider that the start of me becomming a real programmer, and not just some kid that can code.
What was your first language?
Logo! Drawing with turtles rocks so hard. After that it was VB, which let me push Windows around and made me a little cash.
What was the first real program you wrote?
I wrote my first useful program while working as an intern at a financial services firm. The company was using Axys (really bad website alert!) for portfolio analysis and had a tedious process for reconciling their branches with the back office. I wrote a VB program that helped them to perform these reconciliations more quickly, which I hear they still use.
What languages have you used since you started programming?
Logo, VB, C, C++, Delphi, Ruby, Objective-C, Erlang, Scheme, Javascript, Java, and maybe something else. Of those, I’d feel comfortable working on a project using Ruby, Javascript, Objective-C, or Erlang. I’m skilled enough in some of the others, but have vowed to never use them again. I’ll let you guess which.
What was your first professional programming gig?
2005 at the Nathan Kline Institute for Mental Health. There was a PhD there who needed ImageJ to talk to his microscope over a serial port and to have a lot of old scripts from ObjectImage translated into ImageJ. It was a fun job that let me work at my own pace and play a lot with the art of programming.
If there is one thing you learned along the way that you would tell new developers, what would it be?
Surround yourself with great people, and never be the smartest guy in the room. If you’re lucky enough to work at a company with some great programmers, you’ll learn a whole lot that way. If your company is full of 9-5 coders, join a local developer group or start your own. Nyc.rb and Philly On Rails totally rock, so you could always move to New York or Philly and learn from some of the best.
What’s the most fun you’ve ever had programming?
Logo. I used to love making that little turtle draw all sorts of fun things on the screen. There was no real need to make the turtle do things, I was doing it just for the joy of it. I managed to recreate some of that feeling when working on spec-unit, which is really my only useful open source contribution to date. Unfortunately, it only has one release ever, and I haven’t messed with it in two years.
On Working Remotely
Being on my honeymoon in St. Barths has got me thinking a bit about working remotely. Don’t worry, I’m not working on this trip. I’m more trying to think if ways I could stay on this trip indefinitely, but still manage to make some cash.
I’m no stranger to remote work. As some of you may know, I live in Philly but continue to work for Motionbox in New York. I commute two days per week, and spend the rest working from home in Philly. Over the past year, I’ve started to catalog my likes and dislikes with this arrangement, and I’m going to list some of my dislikes here along with some possible ways to improve things. For now, we’ll just look at the first problem I’ve encountered:
You’re out of touch
If you’re distributed while the rest of the team is collocated, you will be out of the loop. When your boss is walking around the office and stopping at various desks, he won’t be stopping at yours. If you’re looking to be recognized for your accomplishments, this can be a major problem. It’s difficult to advance in the company if you’re not visible.
To combat this problem, I’ve found getting everyone on IM and IRC to be very helpful. If your company uses an open office, you’re in luck. The noise from the floor plan typically causes people to use headphones, so they’ll be much more prone to use IM and IRC for all their communication (even with those people right next to them). Another good technique is to send copious amounts of email. If people are cataloging what should be done and who has done what through email (a good practice regardless), then it’s much easier for you to keep track of what is happening in the office.
I don’t think that Skype or frequent phone calls help much in this regard. Typically, you’re only talking to one person and all the speaker phone arrangements I’ve seen aren’t that great. Voice is great for quickly hashing out the details of a plan with one other person, but is terrible as a mechanism for keeping up with the goings on of the company.
Making time (and spending the money) to get to the office at least once a month is invaluable. Though email, IM, and IRC help, they’re not a real substitute for quality time in person. One of the most important things I’ve done at Motionbox is to know when people are going out for after work drinks to celebrate various accomplishments and made sure that I was able to be in town for them. Though it sounds silly to talk about drinking as an important part of work, the main thing you miss by being remote is the social component. It’s much more important to get in town to socialize than it is to do actual work. You’ll have plenty of time to work when you’re home alone the next day.
Anyone have any thoughts on other ways to keep in touch while working remotely?