• We’re hiring!

    We're looking for an awesome Ruby developer to join our team. Get more details at http://devver.net/jobs.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on June 15th, 2009 by Ben in Uncategorized and tagged .

  • Boulder CTO Lunch with Matt McAdams

    Dan usually goes to the Boulder CTO lunches, but he was out of town this month, which meant I had the pleasure of hanging out with some of Boulder's best and brightest.

    This month's guest was Matt McAdams of TrackVia. TrackVia is an online database that is powerful yet simple enough to be used by people who are used to keeping data in spreadsheets (primarily business people). Matt gave a candid and often hilarious talk that touched on both both technical topics, and, luckily for me, a discussion of pricing and metrics, which are two topics that I'm currently very interested in.

    On technology decisions:

    Matt wasn't a database guy originally, but used his practical knowledge he gained working on a previous startup

    Went with the simplest design that could work and it's continued to scale well

    Smart technology decisions have allowed TrackVia to compete with a small, lean development team

    On product development:

    TrackVia started as a contract project for a single customer, but they saw the broader appeal

    One of the earliest databases in TrackVia is the bug database (still around).  In other words, they've been dogfooding since day one.

    They don't worry about the competition. Instead, they focus on building the features that get people to sign up and pay.

    On pricing:

    You've got try stuff and iterate. TrackVia has changed their pricing several times.

    Customers on the old pricing models have always been grandfathered in.

    Sometimes raising your price can actually gain customers because some people assume that a cheap product or service must be low-quality (even if it's actually very high quality).

    If big customers really want feature X, it's OK to ask them to pay extra to accelerate the development of that feature (or to customize their experience).

    On metrics:

    Good metrics allow you to try different strategies and measure their effect.

    You must measure, tweak, and iterate.

    If you can iterate on a weekly basis and your competition can iterate on a quarterly basis, you'll win.

    Metrics must continually be improved. TrackVia spends a lot of time tracking useful metrics, but even they know they need to add additional metrics in some key areas.


    As usual, the CTO lunch was a great place to hear from other Boulder companies and I learned a lot. Thanks for everyone who attended and special thanks to Matt for leading our discussion.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on June 4th, 2009 by Ben in Boulder and tagged , , , .

  • Devver.net has a new look!

    Tonight we just launched the brand new version of Devver at http://devver.net. It's not perfect (yeah, yeah, we know the blog doesn't match - that should be fixed in the next week or so), but we're trying to "release early, release often." Let us know how you like the new look and how we can improve it!

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on May 14th, 2009 by Ben in Uncategorized and tagged , .

  • Our Tools & Practices for Remote Collaboration

    Last week, we had Avdi, the newest addition to our team, join us in Boulder, CO. It was great to get some face-to-face time, since Avdi will primarily be working from his home in Pennsylvania while Dan and I continue to work in Boulder.

    We are excited about the benefits of having a distributed team, but we're also aware that there are a number of challenges. As a result, one of the things we worked on last week was figuring out the tools and practices we'll be using to work effectively from across the country. Luckily, both Avdi and Dan have experience working remotely which we can draw upon.

    We evaluated a number of options, but settled on the following tools and practices.

    Practices

    • Daily Standup. Every day at the same time, we all get on video chat. We cover what we did yesterday, what we're working on today, and whether or not we're blocked on anything. The goal is to keep this meeting at 15 min or less.
    • Minimize interruptions. Whenever we need to communicate with each other, we try to do so on the channel that is the least disruptive (and disrupts the fewest team members). Of course, sometimes we need to be disruptive if an issue is pressing, if someone is blocked, or if we need to have high-bandwidth communication (information, especially cues like body language, don't come across very effectively on channels like email)
    • Keep it simple. We want to use the smallest number of tools and channels that will allow us to work effectively.

    Channels and Tools

    Less
    disruptive
    More
    disruptive
    Channel Tool Properties
    Passive Updates Present.ly
    • Asynchronous
    • Not required reading
    Email Any email client (in practice, Gmail)
    • Asynchronous
    • Required reading (usually)
    • Sometimes time-sensitive, sometimes not
    IM Skype
    • Semi-synchronous (but usually synchronous)
    • Usually time-sensitive
    Voice/video chat Skype
    • Synchronous
    • High bandwidth* (especially video chat)
    • Best for meetings

    * By "high bandwidth", I don't mean that the tool itself requires a lot of TCP/IP traffic (although this is true, it doesn't really matter). What I mean is that we can communicate a lot of information between team members in a short amount of time.

    Other Tools

    • Lighthouse for issue tracking
    • GitHub for source control and our project wiki
    • RealVNC for screen sharing (essential for remote pair programming)

    This is our first attempt at finding a good set of tools and practices for remote collaboration. As time goes on, we'll undoubtedly iterate and improve upon these.

    For another perspective (with a slightly different set of tools), here is a presentation from 2008 about virtual teams.

    What tools and practices have worked (and which have not worked) for your team?

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on April 28th, 2009 by Ben in Development, Devver, Tips & Tricks, Tools.

  • The newest member of the Devver team

    Dan and I are very excited to welcome Avdi Grimm to our small team here at Devver. Avdi has over ten years of professional experience working at Raytheon and MDLogix and has created and contributed to a number of open-source projects. He shares our vision of bringing developer tools to the cloud, our goal of using testing to consistently deliver high-quality software, and our commitment to openness between our company, our users, and the community at large. Welcome, Avdi!

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on April 15th, 2009 by Ben in Devver.

  • Lessons learned from our hiring process

    We're very happy to announce that we've had a great developer accept our offer to join our team. We'll have more details on our newest team member soon.

    This was our first attempt at hiring and we certainly learned a lot. While our process has improved since we started, it's still a work in progress.

    The first lesson we learned is that hiring can take a long, long time - in fact, much longer than we expected. I looked back through my emails and we officially started looking for someone more than four months ago. One thing we have heard time and time again was the importance of hiring only the best people - and, just as importantly, people that fit well within your company culture.

    As a result, we were extremely picky when it came to candidates. As the process goes on and on, it's easy to get frustrated and want to lower your bar. Avoid this temptation! If at all possible, go the other route: raise your compensation, improve your pitch, and raise your profile so you can attract candidates that meet or exceed your bar.

    When we started, we severely underestimated how long it would take and we overestimated how many applications we'd get. Because of these bad assumptions, we made our first mistake - we chose to slowly "roll out" the announcement that we were hiring. First, we just told friends and mentors. A week or so later, we tweeted and put up a blog post. Later on, we posted on some news sites and newsgroups. And after that, we finally created a job posting at Startuply. Waiting between each step was a waste of time - we should have just broadcast as loudly as we could the first day.

    We ended up getting a good number of applications, the vast majority of which were from great programmers. We assumed that going through them would waste a bunch of time. We were wrong. In reality, it was really easy to turn down many applications just from their resume (usually the applicant was good, but didn't have the skill set we were looking for). Phone calls were a bit more time-consuming, but were never a waste of time. We always enjoyed talking to candidates, always found a way to improve our process, and usually learned something new about the Ruby ecosystem.

    One thing that we improved on was learning to say "no" quickly. Even with the manageable number of candidates we talked to, it was important say "no" as soon as we discovered something that wouldn't fit. Early on, we were a bit hesitant to do so and ended up continuing our process for too long. That wasn't fair to either ourselves or the candidates. It became easier to shut things down quickly once we had interviewed a few people and started to gain confidence that new applications would show up, even if the queue was currently empty.

    We also learned that it's important to have a fairly short process. Of course, the biggest priority is to have a process that lets you learn enough about a candidate to be confident in your decision. That said, as you improve, you'll find that you can shorten your process while maintaining your confidence. Shortening the process is better for you (less time spent) and better for your candidates.

    The initial version of our process went something like this:

    1. Check resume, blog, Github account
    2. Introductory phone call to learn about candidate and convince them Devver is cool
    3. Second phone call to ask some high-level technical questions
    4. Ask for and call references
    5. Remotely pair on a project for a few hours with the candidate
    6. Fly candidate out to Boulder to meet and discuss technical and business issues

    The final version was a bit more compressed:

    1. Check resume, blog, Github account
    2. Phone call to learn about them, introduce ourselves, and cover high-level technical questions
    3. Ask for and call references
    4. (In parallel with #3) Ask candidate to write small Ruby application and review their code
    5. Fly candidate out to do some pair programming and discuss technical and business issues

    All in all, it was a good (if sometimes painful) learning experience. We deeply appreciate the time and effort spent by every single applicant (and their patience with us as we learned by trial and error).

    If you've got your own lessons you've learned while hiring, please let us know. We know we've still got a lot to learn...

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on March 27th, 2009 by Ben in Boulder, Devver.

  • Devver.net in closed beta!

    Today we released the beta version of Devver.net to our initial set of users. This release is a major milestone: while our alpha release showed that the concept could work, it didn't have the security or scalability for real-world use. This beta is a solid foundation for us to build on in the months ahead.

    We're happy to have this release out, but it was certainly a difficult experience - we spent over two months on this release, which is more than a month longer than we expected. We've learned a lot from this - most importantly, that it's very difficult to predict the time to complete large releases. We felt it was necessary to make the big changes now, but going forward we'll be moving to much shorter release cycles (every 1-2 weeks).

    In the coming months, we'll be looking for people to try out our beta. If you have a slow Ruby Test::Unit test suite that you'd like to speed up, contact us and we'll put you on our list.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on February 13th, 2009 by Ben in Devver.

  • Using Ruby to Send Update Emails to Our Mentors

    At Devver.net, we send out weekly email updates to an awesome set of mentors. We do this for a number of reasons. First and foremost, we get valuable feedback and advice from our mentors on a variety of issues. But it's also an easy and effective way to keep us on track and even maximize our chances of success. As Paul Graham says in How Not To Die (he was talking directly to YC teams, but you'll get the idea):

    "For us the main indication of impending doom is when we don't hear from you. When we haven't heard from, or about, a startup for a couple months, that's a bad sign.

    ...

    Maybe if you can arrange that we keep hearing from you, you won't die.

    That may not be so naive as it sounds. ... [The] mere constraint of staying in regular contact with us will push you to make things happen, because otherwise you'll be embarrassed to tell us that you haven't done anything new since the last time we talked."

    Foodzie started emailing their mentors early in the summer. We actually borrowed (stole) their email format and best practices.

    One thing we've tried to not do is send out a completely generic email to all our mentors. Depending on the content and the interaction we've had with a specific mentor, we'll adjust his email accordingly. We begin each email with their name and send it directly to them (in other words, we don't put a huge list of addresses in the To, CC, or BCC fields). We do this because we can tailor it and it helps elicit individual responses from each mentor (it's easier to ignore a question if it's sent to a group).

    But, of course, sometimes the emails to a few mentors can be identical. In this case, my not-so-well-kept secret is that I just use a simple Ruby script to send out a duplicate email that appears to be hand-crafted (or at least copied and pasted).

    I've been told that Outlook can perform this functionality easily, but I don't know of any way to do this within Gmail. If there is, let me know so I can feel a little silly (in any case, the Ruby code was fun to write).

    To run this code, you'll need to install the highline gem. You'll also need to add your Gmail account, recipients, subject message, etc. Finally, you'll want to put your message inside a separate file within project directory. That way, you can easily modify, spellcheck, and format to your heart's content before sending.

    You can get the entire gmailr source code (all two files!) at Github. Please use this script for good, not evil - no one likes a spammer. Enjoy!

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on January 20th, 2009 by Ben in Development, Devver, Hacking, Ruby.

  • Devver.net is hiring!

    We are looking for a top-notch Ruby hacker who wants to help us build the next generation of developer tools.

    At Devver.net, you'll be solving new and interesting problems on a daily basis. You'll help us improve our architecture and build new features.

    If you have a passion for Ruby, developer tools, and highly distributed systems, please read more about the job and contact us at jobs@devver.net

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on December 2nd, 2008 by Ben in Devver.

  • Building a iPhone web app in under 50 lines with Sinatra and iUI

    One awesome thing about the iPhone is that it can display documents very nicely, including Word, Excel, and PDF files. However, the other day I was complaining that it's not very easy to view the documents you store on your computer on your iPhone. Sure, you could email them to yourself, but then you have to search through your mail on your iPhone to find your documents. And I'm sure there is a snazzy iPhone app from the App Store to do this as well. But instead, let's build a quick web app using Sinatra and iUI.

    Here's what we'll be building (screenshot courtesy of iPhoney, which rules, by the way):

    A screenshot of the butler iPhone web app

    It doesn't look like much, but hey, it's less than 50 lines of code

    When you click on git-tutorial.pdf, you'll see the full document

    When you click on git-tutorial.pdf, you'll see this

    Sinatra is a really awesome minimalist web framework. It lets you build web applications with just a few lines of code. iUI is a collection of JavaScript, CSS, and images that lets you easily make your web sites look great on the iPhone. Using these two tools, it's really easy to build simple iPhone apps.

    To begin, install the Sinatra gem:


    > gem install sinatra

    Now, let's start with a simplest version of our app, which we'll call 'butler'. Let's make a directory for butler.


    > mkdir butler
    > cd butler
    > touch butler.rb

    Open up butler.rb in your favorite editor and type:

    Now start butler on your command line: > ruby -rubygems ./butler.rb and point your browser to http://localhost:4567 (you can use your computer's browser or the one on your iPhone - it doesn't matter. I find it's better to use the one on my computer while building the app, since it's easier to read Sinatra's debugging messages if something goes wrong). You should see a page that just says "Your files, sir." Congrats! You've made your first Sinatra app. Wasn't that easy?

    OK, let's make butler a little more useful. Sinatra will serve up any files in a subdirectory named public. Since we'll eventually be using this public directory for holding other JavaScript and CSS files as well, we'll actually put our files in ./public/files. We'll also make a link for convenience. Finally, while we're at it, let's put a few test files in there.

    > mkdir -p public/files
    > ln -s public/files files
    > echo "foo" > public/files/foo.txt
    > echo "bar" > public/files/bar.txt

    We want butler to link to each file, so let's build a little helper for that. In Sinatra, you can include helpers within a helper block. We'll also try out our helper for one file.

    Go refresh your browser to see the changes. There's no need to restart your application, because Sinatra automatically reloads changes (very cool!). You should see a link to foo.txt. Click on it, and you'll see the contents.

    Clearly, we don't want to hardcode this for just one file. Let's alter butler to look for every file within the ./files directory.

    OK, refresh your browser and you should see both foo.txt and bar.txt. This is looking pretty good, but we're not really creating valid HTML right now. We're missing html, head, and, body tags at the very least. We could add this all within our "get" handler, but that would clutter up the code.

    Instead, let's put this code into a view. Sinatra actually lets you put the view right after your other code, so you can build an entire application in one file. For simplicity, I'm going to do that for this tutorial. However, if this approach bothers you (or just messes up syntax highlighting in your editor), rest assured you can place the view code in a views directory and it would work the same way.

    Let's add the view to the end of our file, and use it in our handler. Notice that I name the view 'index' by beginning my declaration with @@ index - if I wanted a separate file, I would just put it in ./views/index.erb (you can also use Haml, if that's your cup of tea). Note I assign @links in the handler and it automatically is available in the view.

    Refreshing the browser now isn't really that exciting, since things look the same, but if you wanted, you could easily play around with the view to make things look different.

    One glaring problem is that this page isn't very usable on the iPhone itself. That's where iUI comes in. Start by downloading it (URL is in instructions below) to your butler directory, unzipping it, and copying the necessary files into your public directory.


    > mkdir iui
    > cd iui
    > wget http://iui.googlecode.com/files/iui-0.13.tar.gz
    > tar -xzvf iui-0.13.tar.gz
    > cd ..
    > mkdir public/images
    > cp iui/iui/*.png public/images
    > cp iui/iui/*.gif public/images
    > mkdir public/javascripts
    > cp iui/iui/*.js public/javascripts
    > mkdir public/stylesheets
    > cp iui/iui/*.css public/stylesheets

    To use iUI, you'll need to include the JavaScript and CSS in your view. You'll also need to add some elements to the body of your view. When you're done, the view will look like this:

    This html is probably a bit confusing, but don't worry. There are a few examples in ./iui/samples/ to learn from (and good iUI tutorials on the web). Finally, you'll want to alter the file_link helper to print out iUI code, like so:

    Note that target='_self' code. You need that to get iUI to open a link in a normal way. If you leave it off, it will use an AJAX call to load the file within the current page, which looks really funny when you try to open a binary file like a PDF.

    The final code looks like this:

    And there you have it - an iPhone web app in less than 50 lines of code, thanks to Sinatra and iUI. Now, whenever you want to view some files on your iPhone, either copy the file:

    > cp path/to/my_file ./files

    or if you prefer, link it:

    ln -s path/to/my_file ./files

    ... and then run butler

    ruby -rubygems ./butler.rb

    Figure out the IP address of your computer and simply point your iPhone browser to http://<ip>:4567

    I use butler primarily within my home network, but if you want to be able to view your files on the go, you'll need to poke a hole in your firewall. That's a bit outside the scope of this tutorial, but a quick Google search should give you some good results.

    Enjoy!

    Update: Removed an unused parameter from the code after pmccann called it to my attention.
    Update: Added -z option to tar after Peter pointed out the omission. The tar command without -z worked for me on OS X 10.5, but this is definitely more correct.
    Update: Added -rubygems option to ruby command. If you'd prefer to not use this option, check the comments below for ways to use RubyGems in a Ruby script.

    Got a slow Test::Unit or RSpec suite?
    Devver can run it up to three times faster! Request a beta invite today.

    Posted on November 25th, 2008 by Ben in Hacking, Tools.