At Pivotal Labs last week we watched Linus Torvald's Google talk about Git, the Source Code Management (SCM) system he wrote and uses to manage the Linux kernel code.

I've watched it twice now and here are some thoughts, based on quotes and themes from the video.

"I Never Care About Just One File"

Linus stated that one of the reasons Git was wonderful for him is that, as a high level code maintainer, he needs to merge thousands of files at once. In fact, he stated that he never cares about just one file.

Not so for me. As an in-the-trenches developer, my whole life is caring about just one file, over and over again. When I merge, I care about each file because, since I work on small teams and with small codebases, there is a fairly high likelihood that my changes will collide with those from another developer.

"The Repository Must Be Decentralized.... You Must Have a Network of Trust"

Linus made the point that central repositories suck for large projects where the morons must not have commit access -- only the super privileged are allowed to commit code back to the repo. He argues that Git is better because it is a decentralized network of repositories -- there is no central master, only Some Dudes who have repositories. Usually there is Some Dude In Charge, like Linus, and everyone tends to pull code from them. To update the "master" code version, Some Dude In Charge pulls code from the repositories owned by Some Other Wicked Smart Dudes, who have most likely pulled code from Some Other Trusted Dudes (And One Gal), and so on. Thus, rather than limit access to just the hand-selected few, everyone has their own local copy of the repository, and the smart merge from the smart who merge from the smart, resulting in some kind of official or de facto version.

While I like the local copy of the repo idea, Pivotal does not work the way Linus describes... but Pivotal is weird, in a good way. We all have full commit rights. Our network of trust is everyone. The Dude In Charge is named Continuous Integration. CI makes the official versions. CI runs the tests. CI makes sure that the deploy process works. I'm sure that we could coerce Git into working in a centralized-like way, where it merges automatically from the individual developers and runs the builds, but I'm not sure if that would be forcing a square peg into a penguin-shaped hole.

"Some Companies Use Git And Don't Even Know It"

Linus described how developers at some companies use Git on their development machines, committing their changes and merging fellow developer's changes with Git, then pushing those changes to central SVN repos. He rather mocked this, but it actually sounds like a good solution: developers merge, so use the tool that's good at that. CI machines and deploy machines love centralized master repositories, so use that for those jobs.

"It Does Not Matter How Easy It Is To Branch, Only How Easy It Is to Merge"

Well said. I never thought about that before but he is completely right. I could never put my finger on why I never branch in SVN, even though it's practically 'free' and easy to do. Now it's obvious: who cares how easy it is to branch when merging sucks? Git is supposed to make merging incredibly easy because Git is content-aware rather than just file-aware... or something like that. I'll believe it when I see it, but if Git really does make merging highly divergent branches easy then I'll give it a try.

Joe's Take

I'd like to try Git, especially if it makes branching and merging those branches as easy as Linus suggests, but I don't think that Pivotal would get as much benefit out of it as large, distributed open source projects. A 'really big' project might have 10 developers, not thousands, and all must have commit rights. Our network of trust goes like this: if you are here, we trust you; if we don't trust you, you have to leave. And the idea of having to merge directly from my fellow developers sounds like a pain in the ass... why would I want to merge from 3 separate pairs when I can pull code from the central repo and be reasonably sure (thanks to CI) that it is clean and green? Hopefully I'll be able to answer those questions soon by using Git on a project.

I wrote the following in response to a coworker's questionnaire about continuous integration (CI):

CI's impact has been higher on some projects, while lower on others. If we are including past companies and projects, CI was extremely valuable when builds took a very long time to run on an individual's workstation (such as hours) and when CI tests things that are "hard" to test locally, such as deploys.

In general, CI becomes more important to me as the project becomes larger (resulting in longer test runs) and more complex (resulting in longer overall builds plus technical overhead/pain-in-the-ass factor). For those reasons I really like having CI set up at the beginning of a project in preparation for the impending time-consuming pain-in-the-ass.

Specifically for projects I've worked on, here's how CI has affected me:

  • Previous project: Tests took a long time to run because of a huge Selenium suite, so offloading it CI was nice.
  • Current project: Test suites, including Selenium, do not take very long so the time savings is not such a big deal.
  • Both: Deploy testing is invaluable. We have a complex deploy process at and I sleep better at night knowing that CI is exercising this every time it runs successfully. If CI did nothing but deploy testing then it would be worth it.

Where broken builds have hurt me:

  • For both projects a consistently red CI usually meant timing issues in Selenium. On a previous project these were especially annoying, since the build took over 30 minutes. In both projects we have solved these, but they were rarely if ever indicative of a "real" problem -- instead, the we had to make the testing framework handle the timing issues. The end result was that I was "not allowed" to do deploys because our deploy process, if you follow it, relies on a successfully CI run. This is not a criticism of the process: I wish everyone would strictly follow the CI-reliant deploy process because it brings order to chaos and will save you from shooting yourself in the foot by deploying bad code.

"I'll take CI if I can get it, but I don't really care THAT much whether it's there or not".

  • Sometimes. It's a continuum. When a project has no deploy process and test take 1 minute run, and the team is 1 pair, then CI is a sledgehammer hitting a nail. For projects larger than then my-workstation-can-quickly-handle-it situation, with long, complex test suites, complex deploy process, CI is very valuable.
Installing Ruby on Rails on Ubuntu and Windows XP at the same time under Parallels
Installing Rails on Ubuntu and Windows XP at the same time under Parallels

Now that I have my Ubuntu Linux and Windows XP virtual machines running in Parallels (see Street cred? No: Geek cred (Part 1 of 2)), it's time to set them up to run Ruby on Rails. Why? You know... because.

Again, I'm not going to go into excruciating detail, but instead reference the sites that helped me with this and the problems I faced. Luckily there were only a few.

Windows XP + Ruby on Rails == Easy

Here I pretty much followed the instructions on the main Ruby on Rails site. As much as the Rails community loooooooooves their Macs, getting Rails up and running on Windows is much, much easier and faster than any other OS. No ports, no compiling, no apt-get install voodoo. It's just double-click and next-next-next-next-next...

  • download and install using the ruby windows .exe installer. Make sure you select "enable gems" when asked!
  • download and install mysql
  • gem install rails -y
  • gem install mysql -y
  • gem install mongrel_cluster -y

Ubuntu Linux + Rails = Funkadillio

The guide to installing Ruby on Rails on Ubuntu Dapper Drake at Urban Puddle was a very good guide, but I still had troubles. The issues had the same theme: I needed development/compilation tools, which I had not installed as part of the Ubuntu install process. Here are the other things I needed to do:

Ruby Dev Library

I got the following error when trying to gem install mysql -y and gem install mongrel_cluster -y:

extconf.rb:1:in 'require': no such file to load - - mkmf (LoadError)

Solution: install ruby1.8-dev:

sudo apt-get install ruby1.8-dev

make And gcc

The mysql and mongrel gems also complained about make and gcc not being found:

make
sh: make: command not found

and

make: gcc: Command not found

If you get this, install them both:

sudo apt-get install make
sudo apt-get install gcc

Mysql Client Dev Library

I ended up installing this, too, but I'm not sure if it actually fixed anything.

sudo apt-get install libmysqlclient12-dev

That's it so far. I'm planning on setting up the Ubuntu image as a Capistrano deploy target and treating it as a test server.

OS X running Windows XP and Ubuntu Linux virtual machines in ParallelsI'm finally getting around to playing with Parallels Desktop for Mac, specifically the free release candidates for the next version. My geek-meter is rising with every moment. Here are some of the cool things and problems I found along the way. I'm not going to detail a complete install guide, but I will reference the ones I used and give credit where credit is due.

Windows XP on Parallels

The Parallels Release Candidate includes this nice feature: if you already have a Windows installation on your Mac from using Boot Camp, Parallels will let you run it in a virtual machine. This gives you the best of both worlds: a true hardware-accelerated Windows install for games (why else?) that you can also fire up in Parallels when you want to see if your CSS works in IE6 how badly your CSS is broken in IE6.

Problems with Windows XP on Parallels

Parallels wouldn't start my Boot Camp image immediately, instead giving me this error:

Parallels Desktop cannot find necessary drivers to configure your Boot Camp partition. Please refer to Help> Parallels Desktop Help>Using Boot Camp Windows XP Installation for troubleshooting*

... and so I did. Help> Parallels Desktop Help>Using Boot Camp Windows XP Installation suggested the following:

  1. Boot into Windows XP via Boot Camp
  2. Insert Microsoft Windows XP installation disc which was used for this Windows XP installation.
  3. Locate the folder i368 on the disc and open it. Copy the following files: driver.cab and any of spN.cab files (sp1.cab or sp2.cab, etc depending on service package installed) to the folder: C:\WIndows\Driver Cache\i386.*

... and so I did. The virtual machine worked fine the next time I ran it, no problems.

Ubuntu Linux on Parallels

Nothing very exciting here. When creating the virtual machine, I created a "custom" installation of "Linux/Other Linux kernel 2.6"; this worked fine (mostly... keep reading.) Download yourself an ISO disk image from Ubuntu's download site or bittorrent one. I'm using Dapper Drake (6.06 with Long Term Support). When prompted to "Insert Linux Kernel 2.6 installation CD," choose "More Options" and specify the location of your downloaded ISO.

Problems with Ubuntu Linux on Parallels

I had to install it twice for some reason, which means that I had to delete the first virtual machine I crated and start from scratch. There was some kind of fatal error that I didn't pay attention to at the time, and thus I cannot tell you what it was; now unhelpful of me.

Next up: setting up the virtual machines for Ruby on Rails development.

*Text is most likely © Parallels. Hopefully they will be nice and let me help people help themselves and also sell more of their product.

Does you're company have one of these?

digital whiteboard

It's a super fancy digital whiteboard/printer! I've worked for 2 companies with these things. It was supposed to be a killer app, so to speak, since many of us have had the same thought: wouldn't it be great if we could get a print-out or digital copy of our whiteboard diagrams? Imagine that! So some company invented this contraption with a printer built right in, which could also scan the drawings and save them as digital images. And guess what?

Nobody used it. Not even as a regular whiteboard. Why? Several reasons:

  • It was never plugged in.
  • Nobody knew how to use it.
  • It was small: about 1/4 the size of a "real" whiteboard around which several people could gather around.
  • Dry-erase markers acted more like semi-permanent markers, smearing and marring the writing service.
  • There was something scary about it. I can't explain it.
  • Did I mention that it was never plugged in and nobody knew how to use it?

Note that while I am bashing the digital whiteboard, I'm not bashing the plotter, printer plotter which does rock, though occasionally print The World's Largest Email when you forget to change your target printer.

Don't Erase That!

At Pivotal Labs we make high-tech digital copies of our whiteboard drawing and notes all the time: we use a digital camera. Before erasing a whiteboard that I want to use, I fetch my Canon PowerShot SD450 Digital Elph, a teeny-tiny 5-megapixel camera, which I have in my backpack at all times (please don't jump me if you see me on the street.)Canon PowerShot SD450 Digital Elph camera Then, after taking the pic, I run over to the HP all-in-one color printer we have, pop the Elph's SD card into the memory card slot, and print the pic right then and there. When it's done, I tape the print next to the whiteboard and write the date on it. There. Documented. High tech, yet simple. This also works great for marathon UI mockup sessions and you want to reuse the whiteboard: snap a pic, print it right away, and tape it up. And digital copies? 5MP worth!

Check Out the Pivotal Labs Blog

February 6th, 2007

... because it's where I work. We're still working on content.

http://blog.pivotalsf.com

Today, as we do every 3rd Thursday, Pivotal Labs has our Retrospective, a beer-aided romp though the last 3 weeks of Smilies, Quizzicals, and Frownies: that is, the Good, the Questionable, and the Bad.

Retrospectives are a core practice of many Agile teams, since they represent a dedicated time and place to discuss those exact topics: core practices. We try (and often fail) to stick to non-technical issues, but hey, we're geeks, and discussions often dissolve into passionate PC vs. Mac vs. Linux debates and the virtues of specific keyboard mappings. But, I digress. Here's a quick narrative about our Retrospectives and what we try to accomplish.

On day 1, the day after the last Retrospective, we place a large, sticky-backed sheet of paper against the Whoo-Ha wall (don't ask). This sheet has 3 columns: one marked with a large Smiley face, one with a quizzical/not-happy-but-not-sad face, and the last column topped with a frowning face. Over the next 3 weeks, as various successes, happy events, questionable activities, and frustrations arise, we write them down in the appropriate column. For us, perfectionists that we are, the Frownie column fills up fast and occasionally requires extra paper. Quizzical is close behind, also filling its space. The Smiley column usually has a sorry few examples of good events, and not because they don't happen, but because we are so self-critical that we feel the need to fix any problem that arises. On retrospective day, folks tend to dredge their memories for those happy bits, say, for example, the launch of our largest customer project in history; oh yeah, that was kinda nice!

And now, finally, it's Thursday, at 4:00pm, and 3 weeks since the last Retrospective... beer run! The nearest Tenderloin liquor store owner loves us.

Upon returning with several cases of brewskies, the Moderator, whom was usually reluctantly elected at that day's stand-up meeting, is trying to get the show on the road. Tops are popped and we're under way. The Moderator reads through the list of ToDo items resulting from the last Retrospective: have those assigned specific tasks followed up on them? Have items assigned to the group as whole been addressed? Discussion enssues.

Now, on to the Big Retrospective Paper: do we start with the Smilies or the Frownies? The Moderator decides. Either way, the Smiley topics go fast, with clapping and laughing involved. Everyone's happy!

Now, the Frownies and Quizzicals. In a company of elite geeks, everyone has an opinion, even if they don't voice it loudly. When I moderate, I try to call on folks that I notice do not speak up much, but it's hard -- assertive and opinionated attendants can dominate the conversation. We've made a lot of progress in this area lately and the results are promising: more voices heard. We spend a lot of time on the Frownie and Quizzical topics: when should we hold stand-up, and what should happen when people are late? What is the best way to roll clients out of our continuous integration environment after they spread their wings and fly off with their own development teams? What's the best way to deal with the fact that developers with laptops "pillage" workstations of monitors, keyboard, mice, etc.? And how about stand-up again? Oh yeah, and about the stand-up meeting...

It's both an science and an art to figure out how much time to spend on each issue, especially those that affect the entire group. Some people just want to move on, while others are far more invested in the same issue and wish to really hash it out. For the most part the group and Moderator combine to decide when to finish a discussion (at least for the time being) and address the next. In the end, every issue raised has a ToDo item directly addressing it, with someone assigned.

After the last item is addressed, everyone feels great on several fronts: We talked about a lot of deep topics! The meeting is over! Beer! It's definitely a group-hug moment.

Now, if we can just figure out a way to get everyone to show up at the stand-up meeting on time...

Today I was pairing with another developer and we got a little ahead of ourselves and committed some rather drastic changes to the trunk/HEAD of our project. After a few more commits it became obvious that we were stepping on several other developer's toes, so we decided to revert trunk back to the revision just before we nuked the codebase.

Unfortunately, nobody knew how to do this, though it seemed like this should be a pretty common task, since just about everyone has wanted to erase the past for one reason or another. It didn't take much Google'ing to find the answer but the syntax was weird enough that I decided to show it here. Thanks Python Software Foundation's How-To for the tips.

The command:

svn merge -r NEW:OLD PATH

Example:

svn merge -r HEAD:101 http://subversion.example.com/project/trunk

Let's say you committed a real stinker at repository revision 20, and, since you've kept committing, the repository is now at revision 22. Here's how to revert HEAD back to the fresh-smelling revision 19. Here's the story:

[~/40withegg]# svn rm test/
D         test/unit/asset_test.rb
D         test/unit/core_filters_test.rb
D         test/unit/tagging_test.rb
...
D         test

Commit it!

[~/40withegg]# svn ci -m'JLM: deleting tests because I am crazy!'
Committed revision 20.

And, after some other craziness, we committed a few more things:

...
Committed revision 22.

Let's undo all of that. First, revert, just to make sure your working directory is clean:

[~/40withegg]# svn revert *

Next, perform the (horribly named for this purpose) svn merge, which will add the clean revision's code to your working directory as changes:

[~/40withegg]# svn merge -r HEAD:19 svn+ssh://joe@example.com/svn/trunk
A    test
A    test/unit
A    test/unit/user_test.rb
...
A    test/referenced_caching_test_helper.rb

Finally, commit the fix:

[~/40withegg]# svn ci -m"JLM: adding the tests back... man that was dumb."
Adding         test
Adding         test/actor.rb
Adding         test/fixtures
...
Adding         test/unit/user_test.rb
Transmitting file data .
Committed revision 23.
[~/40withegg]#

Hope that helps!

Kinesis Training Exercises

January 20th, 2007

I'm barrowing a coworker's Kinesis (as according to plan) and, as advised, I'm working though the typing exercises. Thrilling! And don't forget to take mini breaks: finger stretches, shoulder rolls, resting breaks, the works.

Excercise 1

afrf aded afrf aded afvf acdc afvf adcd

juj; afad juj; afad kik; fsff kik; fsff

graf ollok graf olok bavf luj;; bavf luj;

swsf ljuj swsf ljuj deda lolj deda lolj

Excercise 2

talked staff rolled sale trees goals fluke cackle

talked staff rolled sale trees goals fluke cackle

glowed bigger before scared guild slow liked just

glowed bigger before scared guild slow liked just

sort fool talked staff rolled relaxed tasted

sort fool talked staff rolled relaxed tasted

Mini Break!

Excercise 3

afrf aded afrf aded afvf adcd afvf acdc

juj; afad juj; adad kik; fsff kik; fsff

graf olok graf olok bavf luj; bavf luj;

swsf ljuj swsf ll juj deda lolj deda lolj

fbvf dacd fbvf dacd fvcd dcvf fvcd dcvf

Excercise 4

over believe guild drove still cold sale trees

over believe guild drove still cold sale trees

fold older aloof afar dragged rover lead foal

fold older aloof afar dragged rover lead foal

graft lower grand called glorious fodder cooked

graft lower grand called glorious fodder cooked

cave decade cavalier vacated device facade covered

cave decade cavalier vacated device facade covered

Mini Break!

Excercise 5

tafg flol tagf flol acdc jyuj adcd jyuj

;p;k sxs; ;p;k sxs; aqaf jefa aqaf jefa

azak jmjs azak jmjs hooj saef hooj saef

jnj; swsf jnj; swsf l.lf jaff l.lf jaff

Excercise 6

home jump mild jeweled office sports vacation

home jump mild jeweled office sports vacation

coming divine major going afar faded lukewarm

coming divine major going afar faded lukewarm

forward during action jaded minor azure hopped

forward during action jaded manor azure hopped

quaff ajar squall liver cold sliced jokers squall

quaff ajar squall liver cold sliced jokers squall

believed quivered baked jewelry jumpy buffalo soon

believed quivered baked jewelry jumpy buffalo soon

Mini Break!

Excercise 7

molj cadd molj cadd fafa kiol fafa kiol jauj

hakk jnmj hakk j jnmj najj meff najj meff jauj

frfvf kik,k frfvf kik,k dedcd lol.l dedcd lol.l

swsxjujmj swsxs jujmj aqaza ;p;/; aqaza ;p;/;

Excercise 8

game inside past truly pleased knowledge hide

game inside past truly pleased knowledge hide

examples scold fax zany jail same axes loose

examples scold fax zany jail same axes loose

through nevertheless assuming familiar ridiculous

through nevertheless assuming familiar ridiculous

exchange masked exiled over likes favored sacked

exchange masked exiled over likes favored sacked

backward cerebral handy joust kinship daunting

backward cerebral handy joust kinship daunting

rhapsody walks jokers quail skill zoo oxen dump

rhapsody walks jokers quail skill zoo oxen dump

Mini Break! Plus, a 5 minute break since the stress of the 'micro adjustments' my liniments are making are very stressful to my body.

Excercise 9

zyx wvw tsr qpo nml kji hgf edc ba

zyx wvu tsr qpo nml kji hgf edc ba

zyxw vutsr qponm lkjih gfedcba

zyxw vutsr qponm lkjih gfedcba

zyxwvutsrqponmlkjihgfedcba

zyxwvutsrqponmlkjihgfedcba

Excercise 10

quizzical eloquently exercises bungles however

quizzical eloquently exercises bungles however

banished gourmand zoological abstract concrete

banished gourmand zoological abstract concrete

yourself treatise conditional knowledge ergonomics

yourself treatise conditional knowledge ergonomics

snail diary homer jumpy nail jolly sonar half

snail diary homer jumpy nail jolly sonar half

Mini Break!

Excercise 11

abc def gih jkl mno pqr stu vwx yz

abe def gih jkl mno pqr stu vwx yz

abcdef ghijkl mnopqr stuvwx yz

abcdef ghijkl mnoqpr stuvwx yz

abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz

Excercise 12

manifest juicy lopsided safeguard justified popular

manifest juicy lopsided safeguard justified popular

analysis kilobyte national megabyte transaction

analysis kilobyte national megabyte transaction

destiny opportunity abracadabra limitation daily

destiny opportunity abracadabra limitation daily

bagel zoom goof pretzel prized sage honey nosed

bagel zoom goof pretzel prized sage honey nosed

Mini Break!

How's this for a New Year's resolution: Get in shape! Nope. Eat healthier! Nada. Call my grandma more often! Well, yes, but that's not the point. Here it is:

Switch to a super-ergonomic keyboard.

Most geeks know that repetitive stress injuries (RSI) are a big risk for us, especially software developers who literally type and type and click and click all the live long day. But recently it has dawned on me just how big a risk it is: more and more developers at our small consulting company have RSI problems, ranging from minor annoyances to complete debilitation.

Yo, P: Yes, I'm talking about you.

On Monday, a fellow developer had to stop typing for the week, doctor's orders. And for a coder, that's an issue, since coding-by-thought technology is seriously lacking. This caused me to do some quick RSI-inflicted-peeps math:

  • We have about 20 people in our office:
  • At least 6 have RSI problems that I know of, which means there might be more.
  • 1 has been under doctor's orders not to type for the last year, and another has been told to keep of the keyboard all week.

These folk's ages are, as far as I can remember: early 40s, 39, 34, 32, 27 (no typing!), 23 (no typing!).

23? 27? Oh crap.

I'm 31 years old.

Kinesis Contoured Keyboard

Right now, I have no wrist, arm, or hand problems, save for the psychosemantic tingling I feel right now, but I've decided not to mess around with my software ditch-digging tools. Quite a few people I know swear by the Kinesis Contoured Keyboard, which is a pretty crazy looking device, but is optimized to baby your hands. I'm not looking forward to learning a new key layout, but I'll deal.

Now that kids are growing up in the Internet age, maybe parents will ad a new nag to their arsenal: floss your teeth, put on sunscreen, and use an ergo keyboard.

As a side note, since we practice pair programming at our office, we can absorb RSI-inflicted developers since they don't have RSI-of-the-brain.

NOTE: You might have been redirected here. Don't worry! I've moved my active blog to 40. (with egg)

UPDATE: fixed my bad code...

Here follows my summary of "Why there is no Smalltalk-like [or Java-like] IDE for Ruby," compiled from the over 100 responses the threads on comp.lang.ruby and comp.lang.smalltalk,and the email thread on the Ruby on Rails mailing list . I will do my best not to bodge everything up. Interestingly, many comments on the newsgroups and most of the mailing list revolved around the IDEs are Good vs IDEs are Evil debate, which I might summarize at a later time.

I'll do my best with this! Be gentle.

Code Completion, Refactoring, etc.

It seems that the difficulty of Ruby code completion, refactoring,and pretty much every issue can be summed up as this: Ruby has no abuild-in concept of a live runtime "image" at development time, nostatic typing and method argument/return typing that clearly defines objects and methods, and no compiled artifacts that can be mined for data.

Smalltalk vs. Java

In a very, very small nutshell:

Smalltalk, like Ruby, is loosely-typed and (some say) compiled at runtime, but "runtime" is always happening. Smalltalk is alwayslive, always in a particular state at development time; the concept of"runtime" rather melts away, as there is nothing to really contrastagainst it. The state of the entire Smalltalk environment is saved in an ever-evolving "image" that can be mined for ample data to perform refactorings, code completion, and such.

Java, unlike Ruby, is a compiled, statically typed language, and these two features give an IDE ample data about Java objects at development time.

Challenge #1: Language differences between Ruby and Smalltalk

Ruby and Smalltalk are different beasts, even though they share many language constructs and philosophies, most notably loose typing, blocks, and the ability to "reopen" classes and instances at runtime to add methods, etc. But Smalltalk knows about it's development environment (link):

The Smalltalk language 'knows about' its development environment at quite a deep level. The fact that Ruby does not have any built-in knowledge of an environment makes it relatively hard work to make the language work 'seamlessly' in an IDE - I speak as someone who is trying to do just that :)

In other words, Smalltalk is tightly coupled to it's development environment. Smalltalk IDEs keep track of the state of things by keeping a constantly-evolving "image" of the code, which contains an enormously amount of metadata about the state of classes, methods, etc. For example, take the following example Ruby code, which changes a class named Shoe if a condition is met:

class Shoe
...
end

class ShoeTweaker
   def tweak_shoe
      if (self.i_feel_like_it)
         class << Shoe
            def laces #reopen class Shoe and change it!
               ...
            end
         end
      end
   end
end

If this code were saved in a Smalltalk-like IDE, this possible manipulation of the Shoe class would be stored in an "image", and the IDE (and the Smalltalk runtime environment itself) would forevermore know about this possible change to Shoe. Obviously, Ruby has no such facility built into the language itself. But, as pointed out in in the newsgroup thread, there is nothing preventing an IDE maker from providing this functionality (link):

... [In Smalltalk] methods and classes are /always/ added at runtime -- just as in Ruby.

The difference is that Smalltalk doesn't initialize itself by reading and executing a sequence of class- and method-creation expressions. The definitions already existed when your restarted your image. If you define new classes or methods, /then/ these are compiled at runtime and added to the image, so that if you save the image, |they will be saved too.

It makes Smalltalk /look/ as if it's like (say) C++ -- with a list of classes and methods which "just exist" and you browse over them in the IDE.... It would certainly be possible to create something similar for Ruby, but first it would have to have some way of preserving the state of the /entire/ computation between runs.

Hmm... an image-saving IDE would get around Ruby's interpreted nature, a very common theme pointing to why it's so hard to create a good IDE for Ruby. In Ruby, there are no compiled files or bytecodes to mine for metadata about Classes. The entire object tree is recreated as the script is executed. That said, the ruby Interactive Ruby Shell (irb) gets around this somehow, and if the irb's state could be saved, or always running, or if the editor in an IDE was the irb... This might be a great opportunity to implement a Smalltalk-like image/model paradigm for a Ruby IDE, but not make the same mistake choice :) that Smalltalk made to tightly couple the development image to the language and runtime itself. This might even be better (link):

... there are positive points about decoupling the programming from the environment. ... it is quite possible to introduce behavior that may have seemed neat this time last week but does not seem anything like as good now...

Challenge #2: Language differences between Ruby and Java

This one seems pretty easy to understand:

  • Ruby is loosely-typed, while Java is statically-typed
  • Ruby is interpreted at runtime while Java is compiled

As for the compiled-nature issue, reference the previously written stuff about Smalltalk images for info about how Smalltalk got around this. But, there are some interesting details about how Java IDEs have an advantage (link):

... In Java the IDEs use the front end of a compiler to build an abstract model of your program. The refactorings are actually applied to the model in a provably correct way, and then the changes are reflected back in the code. Having things like method generators, method_missing and dynamic structs makes this impossible to do without being inside a running program that can be inspected, which just won't work for a ruby IDE unless you turn it into a live memory type environment.

Java's statically-typed nature makes the world a relatively easy place to live in for IDEs: A class has X methods, implements Y interfaces, and inherits from Z classes. Method signatures are typed as well: in Java, lookUpNames(List names) takes an object of type List, while Ruby's look_up_names(names) takes... who knows? As long as that object don't blow up if messages are sent to it later, then we're happy. This makes code completion a little hard. Nobody had an easy answer for this (or even addressed it) but I'm sure there are some brute-force ways of implementing this, such as "guessing" Classes, or having the developer pick the Class once and remember it, or simply remembering a linked-list of method calls ('person' was once followed by 'name' and also by 'address', so those will be in the list of possible method calls...)

I'm sure I'm leaving stuff out, and if there are glairing mistakes I'll update this later. Hopefully those who were confused (like me) about why Ruby IDE development is so hard will find this useful.

1 Comments (from old blog):

At 10/29/2006 9:57 PM, Chad Woolley said…

There was a thread I saw recently where someone proposed that the unit tests could be leveraged to help exercise code in the IDE, and help determine the dynamic runtime state of the program. This is interesting, but even with 100% code coverage, you still couldn't ensure that every logic path through your program is covered (Unlike EMMA for java, which does block-level coverage metrics, rcov still only does line-level, and even that imperfectly).

Also, it seems like it would help a lot if IDEs were smart enough to find the areas where dynamic code might cause problems with refactoring (instance_eval, method_missing, etc), and either attempt to automatically handle them, or at least point them out to you and let you handle them.

-- Chad

Tramendus response to my posts to the newsgroups and mailing lists! As of this writing:

I'll be combiling a list of interesting items soon, but overall themes include:

  • Smalltalk "knows" about it's development environment, helping it overcome a lot of issues that Ruby has.
  • Java is combiled + statically typed, helping it overcome issues that Ruby has.
  • Smalltalk and Java have funded projects and are supported by the business community.
  • That said, most of the issues can be overcome in time.
  • Update: people are passionate about their favorite text editors.
  • Update: the "we don't need IDEs" vs. "IDEs are almost essential" debate rages on.

I finally did it: I posted my "Smalltalkers and Rubyists unite for IDE support!" post to comp.lang.ruby, comp.lang.smalltalk, ruby-talk@ruby-lang.org, and rails@lists.rubyonrails.org. We'll see if I get trounced by the communities.

Hi all --

I shout my question to the entire Ruby + Smalltalk community: Smalltalk has had amazing IDEs for decades, why not Ruby? Smalltalkers, Ruby needs your help!

I'm hoping to start a centralized discussion about this topic, since my searches have only turned up scattered comments.

Ruby should have IDE support approaching Smalltalk's based on the following gross generalization: Ruby and Smalltalk are pretty much the same. Yes, I know there are many differences, and not trying to provoke a Ruby vs. Smalltalk cage-match, but based on language features and constructs, they are very similar.

What is holding Ruby back? How has Smalltalk overcome the issues? What can Ruby tool builders (such as the RadRails folks and, hopefully, me) learn from the Smalltalk IDE builders? Reasons I've heard for Ruby's lack of tool support include:

  • Ruby is not a compiled language
  • Ruby does not execute in a VM or run-time
  • Ruby is a loosely-typed language and has blocks, etc.
  • Nobody really cares enough about a Ruby IDE tomake one
  • vi is all you need!

Regarding the compiled language and VM arguments: what about Ruby's irb? Regarding loose typing, blocks, etc: Smalltalk has these! I don't pretend to understand all of the issues, but I want to learn. Unless there is something I simply don't "get", it seems that the Ruby community does not care or see the benefit of real tool support, which leads me to believe that (again) the Smalltalk community is not very interested in Ruby.

I've only been working with Ruby for 8 months after 7 years of Java, but I almost feel like a Smalltalker by association, having worked with, and for, Old Dudes Who Know Smalltalk (yes, I said it) my entire career. I've stepped back into the stone age regarding IDE support after using VisualAge for Java, Eclipse, and InilliJ IDEA. No refactoring, no fast debugger support, not even code-completion/suggestion. To the current tools, Ruby is text to colorize.

Smalltalkers, you've cracked this nut years ago, help us understand how to do it again in Ruby!

-- Joe

http://www.josephmoore.net/

I went to the SF Ruby Meetup for the first time on June 12; great turnout by all accounts, about 80 people or so. The first presenter, Derek Haynes (Highgroove Studios) talked about building the perfect Rails team, and we've done so at my company if you follow his formula. But more interesting to me is this trend, which other might have known for a long time: design-first development.

Here's what I've gleaned from the few talks I've heard about this: in design-first development, server side modeling is almost completely ignored in favor of really nailing the UI design, flow, features, and user experience. Developers/Designers (devigners?) go strait for the HTML, CSS, and JavaScript, mocking out any AJAX calls to make the design seem like it's really talking to the server. This is iterative, but not in the sense that the entire end-to-end system is designed and refactored along the way. Only after the design is whiz-bang'ed and solid do the developers bolt on (my words) a model layer. I've heard this pushed the Haynes talk, and also by web design guru Dan Cederholm (Bullet Proof Web Design and SimpleBits), and by some members of my own development team.

This is completely foreign to me. I'm model guy, an end-to-end guy. I work from the domain model layer out towards the UI, and get a very simple thing working first, then refactor towards the ultimate design. And even then my UI is going too look like cat puke until I feel like I can devote the time to really getting it right, but usually after the model is solid. So my first reaction it to recoiled from design-first development and start saying works like "scaling!" and "domain-driven development!" and "do the simplest thing possible!" and "YAGNI!" and "models should be understood by our customers!". But is this justified? On most of the Rails projects we're developing for our clients, we knock out the server side stuff, including DB, models, and controllers very quickly (and yes, test the hell out of them), then spend the majority of time in Jails (JavaScript for Rails). And when we have had nice mockups from clients we have stuck to them, for the most part. I'll have to talk to some DFD'ers and see how the bolted-on models hold up.


1 Comments (from old blog:

At 6/16/2006 9:55 AM, DrydenMaker said…

I tend to agree with your thoughts. The difference that is evolving is that the UI is putting on weight and there is more programming going on there that makes the server side easier. We are moving toward the 'programmable web'.

DrydenMaker http://webdevsnob.blogspot.com/

NOTE: You might have been redirected here. Don't worry! I've moved my active blog to 40. (with egg)

Normally I don't spam/link post, but this is too important not to shout out to the world: Ruby development, with debugging support, and soon with Rails support, in... wait for it... wait for it...Visual Studio 2005! Check out Steel here:

If you talk to any of my coworkers, they will tell you that I am an Eclipse zealot. I love Eclipse. I love and understand it's way of thinking, and I am the most productive with this IDE. Well, at least I used to be when I was doing full time Java development with Eclipse's Java IDE, which is actually a massive Eclipse plugin. Now I'm a full time Ruby on Rails developer using the painfully poor Ruby/Rails plugins for Eclipse: RDT and RadRails. RDT and RadRails are developed by Some Dudes who are busy either working at real jobs that don't include developing free IDEs for me, or studying for finals and being excited that they are old enough to drink beer. Point being that the IDE support for Ruby and/or Rails is stone age at this point, and 99% of the features I use for Ruby development are not RDT/RadRails features at all, but default Eclipse feature or features from other plugins, such as the HTML, JavaScript, and CSS support from the excellent J2EE Standard Tools project.

If Steel can bring to Ruby/Ruby on Rails development even a small portion of productivity gaining features that I sorely miss from Eclipse's Java IDE, then I will burn my Eclipse Fan Club membership card and send the ashes to Erich Gamma, then buy Visual Studio for my workplace with my own money.

Can you tell I'm excited about this? I'm switching back and forth between writing this post and reading the Sapphire In Steel home page. I've just read the About Us page and I'm getting more insight into why these guys "get it". Here are some snippits:

has spent the last twenty years...

has programmed in languages ranging from Delphi and Java to C# and Smalltalk...

since 1988...

Ah, there it is -- These are Old Dudes! I love Old Dudes! And I really love Old Dudes Who Know Smalltalk! I was nurtured, sculpted, and brainwashed by Old Dudes Who Know Smalltalk from my very first day as a professional programmer, and they universally "get it". Young whipper-snappers out there, take note: if you ever here some Old Dude say the words "in Smalltalk you could blah blah blah" or "In VisualWorks you could yada yada", spend as much time with this person as possible. You will learn more from them about software development than the Young Dude who only wears black and thinks that the bash shell is "too bloated".

And what does "get it" mean? Maybe I'll get into that some other time (it will be ugly, as this is one are where I am very opinionated), but the important thing is this: these guys don't come from the school of web scripting hackery in vi, they come from the land of building real enterprise applications, where real tool support is appreciated. And at this point in the Ruby IDE game, I'd place my bets on them to produce the first a truly usefully development tool.


1 Comments (from old blog):

At 9/30/2006 8:18 AM, Torv said…

Well, finally you get it ;)

www.squeak.org