Thursday, October 25, 2007

Terminate batch job (Y/N)? Y

If you happen to use Ruby/Rails on Windows then you've probably got annoyed at least a few times by the "Terminate batch job" prompt you get when typing Control-C at an irb or mongrel session. Even though the program already terminated after a Control-C, the prompt asks anyway and you are forced to give an answer. That's because those Ruby programs are wrapped inside batch files, which have that behaviour hard-coded into cmd.exe.

It's possible to patch cmd.exe, but if your only problem is with some Ruby scripts, you can simply get rid of the batch files and replace then by pure Ruby scripts.

In the case of irb rename bin\irb.bat to bin\irb.rb and remove the lines from the beginning of the file until goto endofruby. For mongrel_rails delete bin\mongrel_rails.cmd and rename bin\mongrel_rails to bin\mongrel_rails.rb. The steps are similar for other files. Sometimes the Ruby script is coded directly inside the batch file. Other times the batch file just invokes Ruby with another file without an extension. But be sure .RB is appended to the PATHEXT environment variable.

The solution is so simple and yet I took months to finally put it in practice...

Wednesday, October 3, 2007

Persisting variables between partial calls

In Rails, there are times when you need to preserve the value of a variable across partial renderings. For example, you want a partial to render a row of a table with numbered rows. How do you do that?

Store the value in an instance variable:

<tr>
  <td><%= @row_id = (@row_id || 0) + 1 %></td>
</tr>

The variable will be preserved while the page is being rendered, in an instance of a dynamically created class, subclassed from ActionView::Base (as of Rails 1.1.6 that happened in ActionController::Base.initialize_template_class).

The same variable will be available inside the corresponding helper, since the helper is included as a module of that dynamically created class. So code like the one shown above may be moved to a helper.

Use the trick wisely, though! A variable seen by different files is almost a global variable.