Programblings

Rambling about programming and life as a programmer

Archive for the ‘ruby-rails’ Category

Do not learn Ruby

Posted by webmat on February 20, 2008

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-)

Ruby will get under your skin. You will miss its features and quirks when you’re not using it. You might even find other languages insufferable, once you get comfortable with Ruby.

After you’ve started using Ruby, there’s a significant chance you’ll start loathing whatever code base you currently have to work on. Especially if it’s a statically compiled language. A code base you used to think was ok, except for its few quirks.

After a while of perusing the different Ruby-related blogs, you’ll have heard other Rubyists speak of their work with words like beauty, productivity, expressiveness, conciseness, fun and you’ll realize just how far your current language is taking you from all of these words.

You’ll see

Dictionary<string, string> someDic = new Dictionary<string, string>();

And dream of

some_dic = {}

You’ll see multiple declarations for the same method, trying to emulate optional parameters and think of Ruby’s symbols and options hashes, where such a simple method as:

def method_with_options(options = {})
encoding = options[:encoding] || 'utf-8'
puts('Other option detected') if options[:other_option]
#...
end

Enables all of the following uses

method_with_options :encoding => 'utf-16', :other_option => true
method_with_options :encoding => 'utf-16'
method_with_options :other_option => true
method_with_options

You’ll hear about metaprogramming and the complex syntax or frameworks that can bend Java, C# or C++ to allow a programmer to achieve what he seeks.

In the back of your head, you’ll think of the insane flexibility allowed by

- simple Ruby syntax for method chaining or redefinition;

- dynamic class definition, that lets you add methods to any existing class, even Ruby’s core classes;

- duck typing, where objects of any type can be passed to a method, as long as it responds to the expected method calls in a reasonable fashion;

and oh so many other Ruby niceties.

You’ll encounter twisted method definitions such as

bool SomeMethod(int param1, ref SomeClass someClass, out SomeEnum resultType, out string result)

and think of Ruby’s multiple returns that allows you to clearly define what’s a return value and what’s a parameter:

success, resultType, result = some_method(param1, someClass)

You’ll delve into huge, puzzling class hierarchies that struggle just to use the right abstraction level for class names… You’ll eventually realize that the whole hierarchy was simply there to share a few methods among loosely similar classes.

Then you’ll really get irritated at all the accidental complexity that could have been avoided by simply using mixins, where you define a common method and then include it in any appropriate class. And all of this without ever puzzling over strange abstract names for classes that happen to sit between 2 clear-cut levels of abstraction.

You’ll want to explore a new part of the .Net API by playing with it. You’ll create a dummy project in some random directory, find a name for it, include the proper parts of the API in the generic main class created by default and finally start playing with the construct of interest.

All this time you’ll be thinking of IRB, the Ruby interactive console. It not only allows you to play with an existing API with absolutely no fuss, but thanks to Ruby’s flexibility, you can even define classes in the console and then play with them!

But then you’ll think “Oh yeah, IRB is in fact so flexible that I can use if from a frickin’ web page (with a tutorial)!” And you’ll go play there for a couple minutes (when no one’s looking), just to keep you sane for a couple more hours. Until the C++ / C# / Java drudgery is over for the day.

You’ve been warned. If you learn Ruby, you’ll start thinking it’s impossible for you to keep using the technology you’re currently using at work. If you’re patient you’ll try to introduce it there gently (and most likely get frustrated at the time it takes). If you’re not so patient, you’ll just end up changing job.

Next monday I’m joining the great team at Karabunga to work on Defensio. I’ll be doing Ruby and a bit of Rails. Liberation is coming :-)

Posted in garbage out, programming, ruby-rails | 54 Comments »

An easy way to make your code more testable

Posted by webmat on December 13, 2007

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-)

James Golick wrote a very good article about testing a while ago. In it he dissects (and refutes) the too often heard arguments where people say they don’t write automated tests because they don’t have the time.

In the comments, some people concluded that yes, they should try to write more tests, but didn’t know where to start. In this post I won’t suggest frameworks, or specific tutorials. I’d just like to give one very first step that will help you write code that is easier to test. You’ll benefit from it even if you don’t use a testing framework yet.

As the title suggests, what I’m suggesting is pretty simple. Write side effects free methods/functions. Simple isn’t it? The rest of this article is just about explaining my point. So if the light bulb went off already, you can stop reading now.

I’m kidding, of course! So let’s not take anything for granted, instead let’s make sure we’re on the same page and define “side effect free”. It means that a function (substitute with “method” if you like) receives parameters, spits out a result and has not touched anything outside of it. There are two key parts to this definition:

  1. The function does not depend on anything else than it’s parameters: it does not expect a variable to be set outside of it to work properly (at the object, class or global level).
  2. It does not modify anything. Its result can be entirely observed either from the return value or from the exception thrown.

Of course you often have to modify the state of the application as a result of a computation. What I’m suggesting is not a substitute for that. What I’m suggesting is simply to put the juicy bits of your computation in a side effect free function. This part will be trivial to test, but you’ll still have the code that uses this function. That other part, which modifies the state of the app will need unit tests or other higher level testing.

Trivial examples of side effect free functions can be found in any good math library supplied with a language. Of course no modern language expects you to set a global variable in order to compute a square root. Those who want to follow the Ruby examples can do so on Try Ruby (fear not, you’ll be able to follow along even if you don’t know any Ruby).

Math.sqrt(4)

=> 2.0

And

Math.sqrt(-1)

Errno::EDOM: Numerical argument out of domain - sqrt
from (irb):6:in `sqrt'
from (irb):6

So there we have it. The result of squirt is observed either from the return value or from the exception thrown. We don’t expect any state to have been modified anywhere else in the application. I’ll present a less trivial example in a bit, but first let me just say that the direct consequence of writing this kind of code is that you can test it trivially, whatever your technique of choice.

  • If you’re in your debugger or in your interactive console, you can call it as many times as you want, with different parameters and check out if its behavior is what you expect.
  • If you use unit tests, you can code the interesting scenarios and verify their expected outcome, only in a repeatable manner.

Now since we all have a Math library of some sort in our language of choice, let’s look at another example: analyzing the parameters that will dictate the execution of your program. This is valid for configuration files with a bit more work, but let’s keep the example simple and just analyze command-line parameters.

Most languages provide us with some kind of array of parameters when entering our main function. The common way of dealing with them is to slap a big if or switch statement somewhere at the beginning of your program, which sets the state of the application accordingly, before actually starting to work on the application’s main task.

A side effect free approach would be to split the process in two parts:

  1. parse the parameters
  2. set the state / do some work

For example we could define a function that accepts an array and returns a hash (a Dictionary for .Net folks, a Map for Java folks) of the execution parameters:

{

'arg1' => 'val1',

'arg2' => 'val2'

}

So let’s say we start with the following method to analyze our arguments (to see the readable, indented version of this code, look at it on Pastie) :

def analyze_args(arg_list)
parsed_args = {}
#We check that each argument is in the form 'arg=value'
arg_list.each { |arg|
key, value = arg.split '='
if (key.nil? || value.nil?)
raise "Some arguments are not in the 'arg=value' format"
end
parsed_args[key] = value
}
return parsed_args
end

Now we can trivially test the parsing of the command-line params:

analyze_args(["mom"])

RuntimeError: Some arguments are not in the 'arg=value' format
from (irb):23:in `analyze_args'
from (irb):20:in `each'
from (irb):20:in `analyze_args'
from (irb):29
from :0

analyze_args(["mom=food"])

=> {"mom"=>"food"}

analyze_args(["mom=food", "dad=car"])

=> {"mom"=>"food", "dad"=>"car"}

Now that this part is taken care of, I can test it with whatever input I want, trivially.

To reiterate, in order to make your code easier to test, just extract the juicy bits of your program in side effect free functions and keep them apart from the rest of your program, which in turn makes sense of the result. At least the side effect free parts will be trivial to test.

This is just the beginning of the testability and automated tests journey, however. Of course you still have the rest of the program to test, preferably in an automated fashion.

Posted in garbage out, programming, ruby-rails | Tagged: | 23 Comments »

Culture shock

Posted by webmat on November 16, 2007

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-)

I had a bit of a culture shock a couple of days ago. I saw a video of the visual designer for IronRuby, named SapphireSteel. The tool looks very nice and polished.

Something unsettled me, however, when I saw it. It has nothing to do with the team or what the narrator says. In the demo, he shows us a couple of features of the designer, and inevitably we end up seeing snippets of code. That’s when the culture shock, uhh, shocked me.

I’ve seen plenty of verbose code in my time. I even work in C# right now, which I find errs on the side of verbosity. So I’m used to seeing verbose code, and I’m certainly used to see WinForms code.

But seeing this WinForms code in Ruby felt very weird.

WinForms in Ruby is Still WinForms

WinForms code in Ruby is still exactly as verbose as in C#. Only the semicolons are missing.

C# colleagues might tell me that this code just satisfies what the API wants to hear, in the way it wants to hear it. But I’m getting used really fast of the Ruby way of doing things. Which consists “sane defaults” for a start, and using DSLs to solve complex problems in a declarative manner rather than in an imperative manner.

WinForms development with Ruby screams for a Rubyish wrapper. Anybody up for that? If it can be done for Java’s Swing (with Profligacy, the Swing reducer), it can certainly be done for WinForms.

For my part, however, I’d be much more interested in exploring XAML with Ruby, but that’s another story.

Posted in programming, ruby-rails, windows | Tagged: | Leave a Comment »

Follow-up on my presentation on JRuby

Posted by webmat on November 8, 2007

Me, gesticulating vehemently

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-)

I’m very pleased! My presentation went very well, the audience was very receptive. We had some great questions and interactions during the talk. Great fun! Here we can see my neck-twisting setup and me, gesticulating vehemently.

So if you want to check the presentation again for some reason, here it is: JRuby – On and off Rails. Also available is my take on Nick Sieger’s, Rails performance numbers.

I suppose some of you might be interested in my other references, as well. So here’s a recap of the links I mentioned at the end of the presentation.

The people

Charles Oliver Nutter works for Sun, he’s the main driving force behind the compiler, among other things. If you’re interested to hear about easy bugs to fix in JRuby, he posts a list once in a while.

Ola Bini works for Thoughtworks and he also works on JRuby full time. His recent feats include speeding up the regex implementation of JRuby.

Nick Sieger also works for Sun, but his job is on the user end of JRuby. He contributes to JRuby as well, however. And by the way, check out the follow-up on the talk he and his team gave at RailsConf. The article discusses implementing some parts of the model of his application as RESTful services, thus giving them more flexibility for scaling. The WAR file deployment approach is mentioned as a tool that helps manage all those independent Rails instances.

Last but not least, Thomas Enebo, also hired by Sun to work full time on JRuby. During the presentation I mentioned that his blog was less technical than the other guys. Turns out this feeling was largely based on the activity on his blog before summer. Recently he posted some very interesting posts on JRuby and Ruby. Looks like I have some catching up to do :-)

The project

The official JRuby site is hosted on codehaus. While the official wiki is on Charles Nutter’s personal site for now.

JRuby on Rails

For 2 good tutorials that take you through the steps of trying out JRuby, go see on ADS’ blog:

Getting JRuby and Rails running. Deploying to Glassfish. Theirs posts are pretty detailed, but since things are moving so fast in the JRuby world, some of the details are a bit out of date already :-) In it they use Goldspike to generate their WAR archive, just like I did.
As I mentioned however, a post by Nick Sieger introduced me to warbler as another very promising replacement to Goldspike. In fact, as Nick describes warbler, I fully expect to try it and stick with it instead of Goldspike. Definitely worth a try.

Check out the Glassfish gem for a better integration of Glassfish in your Rails workflow. I haven’t tried it yet, so I can’t elaborate on it.

The 2 Java web servers I used are:

Jetty, the small, unintrusive yet very scalable web server. I likened it to WEBrick in that it can be used to try out our WAR file with absolutely no fuss. Which is not to say that it can’t be used in a production setting.

Glassfish, the full-featured server with the admin interface. This is the server that ended up being about as fast as the MRI/Mongrel combination, in the performance comparison.

If you’re interested in a JRuby/Mongrel setup, the one which ended up being the fastest in the comparison, check out this post*, mentioned by Nick Sieger, and this post by Ola Bini.

JRuby off Rails

For those that were insterested in the non Rails bits as well, I talked about an unintrusive plugin that allows you to create Swing gui apps, I mentioned (and stumbled over the name of) Profligacy. It’s been created by Zed Shaw, the creator of Mongrel.

I also talked about using JNA to reuse existing C extensions for Ruby, which do not have a JRuby equivalent yet.

I have to stop and go to work now

Hey, I wanted to make this a short post. Looks like I failed :-) If I forgot something of if you have questions, don’t hesitate to comment. I’ll get back to you and update this post, if necessary.

As for me, I might help Carl by checking out whether JRuby could be a good fit for Defensio. I’m looking forward to that, I think it’s a great real world project to dive into JRuby head on. Of course I’ll report back and contribute, based on my findings.

*Sorry, the JRuby/Mongrel link seems dead as I’m posting this. I leave the link in case the problem is temporary.

Posted in garbage out, ruby-rails | 1 Comment »

Mat mini

Posted by webmat on November 5, 2007

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-)

Good news everyone*!

Tomorrow my presentation at Montreal on Rails is going to be made on my brand new Mac Mini!

In my last post I mentioned I was going to present on an ooooold Win XP laptop, but I decided to make the switch to the Mac world now. Well, one week ago. So fear not, I’m not going to subject our community to a 5 square meters XP/Powerpoint eye bleeding festival.

The Apple world had one little surprise for me, however. Immediately after I bought my Mini I started hearing about the Java 1.6 debacle on Leopard. What? I didn’t event know OS X didn’t come with the standard Java distribution! And here I am, about to make a presentation on JRuby on a Mac :-) Note to self: never switch to a completely new OS (to me) one week before a presentation again.

This won’t affect the presentation, however, since everything works perfectly fine on Java 1.5, preinstalled on Leopard. And isn’t it reasonable to expect Apple to release Java 1.6 shortly anyway? So for those I’ll convince to give JRuby a try, all hope is not lost. Moreover, for the Rails community I think the Java 1.6 story is pretty much a non-issue. Your test and production servers are running on Linux, right?

So with that out of the way, there’s only one bump left in the road. As our host Fred pointed out to me, my mini has only one video out. Doh! I didn’t find any VGA or DVI splitter, so I’ll deal with it. This will be a bit of a pain in the neck, but hopefully just for me :-) Let’s see how the live coding part goes!

* In my best Professor Farnsworth voice (from Futurama)

Posted in ruby-rails | Tagged: | 2 Comments »

JRuby, not in its setting (or configuring jirb under Windows)

Posted by webmat on October 18, 2007

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-)

For a good while now, I’ve been using Ubuntu on my main home machine. Working with Ruby and JRuby on Linux is a charm.

Tonight, as I tried to set myself up to work with JRuby on Windows*, I bumped into an annoying problem. When I tried to configure jirb, the JRuby version of IRB, it didn’t always seem to find the .irbrc config file in my home directory. I looked a bit on the ‘net and found nothing that helped me solve my problem. I’ve worked out a fix, you can follow along in this wonderful adventure.

So to configure irb, I create the .irbrc file in my home directory.

C:\Documents and Settings\Mat\.irbrc

Note: Windows will yell at you if you try to make a new file starting with a “.” in windows explorer. Just use any good text editor to create it directly.

In it I put some configs for auto-completion and auto indent, as suggested on the Tips and Tricks page on the Rails wiki:

IRB.conf[:AUTO_INDENT] = true
IRB.conf[:USE_READLINE] = true
require 'irb/completion'
puts "Yay! Completion's loaded!" #Uhh, that's my special debugging code :-)

Now I fire up a console and start the interactive Ruby shell with

C:\Documents and Settings\Mat>jirb
Yay! Completion's loaded!
irb(main):001:0>

Hmmm, it works. What am I yelling about? :-) Let’s say we fire it up in an actual project directory instead.

C:\projects\an_actual_project>jirb
irb(main):001:0>

Oops! My “special” debugging code isn’t executing now :-)

If you care to see what’s the code that hints at how to solve the problem, you can open

…\jruby-1.0.1\lib\ruby\1.8\irb\init.rb

Or check it out a snippet of IRB.rc_file_generators online.

As we can see, if the HOME environment variable is set, the method looks for .irbrc in the directory, otherwise it looks for it in the pwd (present working directory).

Nice! That explains why it works in my home and not elsewhere :-)

So now I just have to set a HOME variable and I’m all set:

home.png

Now after restarting my console (to have the updated environment variables):

C:\projects\an_actual_project>jirb
Yay! Completion's loaded!
irb(main):001:0>

Note that even though Windows variables are not case sensitive, you must name your HOME variable in capital letters. Ruby expects the ENV hash to contain the HOME variable in caps.

* Q: Why would I want to set this up on Windows, if I’ve got a perfectly good Linux setup at home?

A: I’ll be giving a talk about JRuby at the next Montreal on Rails, and since I haven’t really needed a laptop in at least two years, well, I only have 3 years old laptop. This old geezer can run equally old versions of Linux, but I wouldn’t like my audience to have to suffer the visually challenged distro I currently have on there.

Posted in garbage out, programming, ruby-rails, windows | Tagged: , , , | 2 Comments »

Free PDF Rails Book for beginner Rails developers!

Posted by webmat on October 3, 2007

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-) 

As seen on the Rails blog, sitepoint.com is giving away free PDF copies of Patrick Lenz‘s book, Build Your Own RoR Web Apps. The offer is good for 60 days. Well, 59d15h at the time of posting :-)

It involves jumping through a couple of hoops, and the book contains a couple of pages containing ads about other Sitepoint books. But nothing too bad, at first sight. And it’s still a free PDF book! So if you know anybody who’s curious about Rails and might want to try it out, you have until the beginning of December to point him/her to rails.sitepoint.com.

Posted in garbage in, programming, ruby-rails | Tagged: | 2 Comments »

Montreal on Rails tonight

Posted by webmat on October 2, 2007

Update: This article has has a new home on programblings.com. Go to the article.
Comments are closed here but still open there :-) 

Tonight is Montreal on Rails #3! I can’t wait to attend: this will be a nice refreshment from my gruesome C++ tar pit at work, ugh! :-)

The first 2 were very interesting and filled with great people to meet. Tonight promises to be just as great, and as a bonus, we’re leaving behind the small McGill University classroom to be welcome instead by Fred and Ben from Standoutjobs. Can’t wait to see that either!

And great big thanks to Mat and Carl for organizing this monthly meetup!

Posted in garbage in, programming, ruby-rails | Tagged: , | 1 Comment »

 
Follow

Get every new post delivered to your Inbox.