April 2007 Archives

Gregory Brown

AddThis Social Bookmark Button

Just because Everyone Is Here In The Future, doesn’t mean you should be too!

The culprit, in camping’s reloader:

86  # The timestamp of the most recently modified app dependency.
87  def mtime
88    ((@requires || []) + [@script]).map do |fname|
89      fname = fname.gsub(/^#{Regexp::quote File.dirname(@script)}//, '')
90      begin
91        File.mtime(File.join(File.dirname(@script), fname))
92        rescue Errno::ENOENT
93        remove_app
94        @mtime
95      end
96    end.max
97  end

If your most recent modified time is more recent than your current system time, your reloader will break until you go Back To The Future.

I figure this is probably a rare case, and not really a bug, but if you’re playing around with system time dependant apps (I am), this might bite you.

Gregory Brown

AddThis Social Bookmark Button

I’m excited to be able to finally get around to another post in this Digging Deep series, in which I hope to delve head first into some Ruby esoterica. This time around, I have an interview with Ara T. Howard about some of the hackery he does with packaging rq

Hope you enjoy it! Questions follow.

Tim O

AddThis Social Bookmark Button

Capistrano 2.0 Preview 1 has been released. The first time I used Capistrano I was blown away by the ease with which you could deploy an application to a production network with multiple application servers.

New features include:

  • Namespaces for Capistrano Tasks
  • Deployment strategies - You don’t have to deploy via a Subersion checkout, now you can export, or you can export locally and copy a tgz or zip to the target server.
  • Environment Variables via the Comand Line

I’m not doing it justice, for more information see www.capify.org.

Namespaces should make it easier to build atop Capistrano…

Namespaces should help projects like Mike Bailey’s deprec which extends Capistrano to automate not just the deployment of a rails application but the installation of a full rails stack.

Cap on Other Platforms

…And, this is the part that interests me, how Ruby, RoR, and the technologies built around them are infecting the broader community. From Ian Sefferman’s blog entry, Capistrano and Java:

Capistrano is definitely Rails tailored. It makes a lot of assumptions (in true Rails philosophy fashion) that make it dead simple to use for your new Rails app. However, there’s nothing really constricting about Cap itself that forces it to be Rails only. Recently, Maurice and I did our first Java project for Openomy. We knew we’d be deploying to more than one box, so we decided we’d try out Cap for deploying a Java service to multiple boxes. I figured I’d write up some of what we learned and what we’d like to change in the future.

Also, see Automated PHP Deployment with Capistrano.

Capistrano is only for crazy Rails apps right? Nope. Its simply a platform for automation. It just so happens that deployment usually requires quite a bit of steps. Hmmm…lots of steps…automation… a match made in heaven. So sure, Capistrano was thought up with Rails in mind, but created openly so you’re able to use it any way you’d like.

Gregory Brown

AddThis Social Bookmark Button

After months of planning and organizing, in just one day GoRuCo has come and gone. The Gotham Ruby Conference 2007 took place at Google’s NYC office on Saturday April 21st. It featured 6 talks, 3 from the tri-state region, three from outside the region, and a round of lightning talks.

As one of the organizers, I can tell you how much work it is to put something like this together. We had a fairly large team and I think we relied on each and every person’s unique contributions to make the whole thing come together. However, to credit our speakers and attendees, our whole purpose as organizers was simply to provide an environment and make sure it stayed functional. It was you guys who brought the show.

Gregory Brown

AddThis Social Bookmark Button

UPDATE: RC3 is out as of 2007.05.08, see release notes for details

Although I do copiously mention Ruport as a sick obsession of mine, I try not to use this blog to directly promote the project.

However, I think that I have some news-worthy info to share about the project, or at least something really exciting to me: We just put out our first 1.0 release candidate!

This is a rough RC, we expect quite a few changes before things finally gel. We also are farther behind on documentation then we want to be, but the functionality is getting quite good and after a 2.5 month hiding period, we’re excited to open the code back up to a whole lot more eyes.

If you’ve seen Ruport in the past, you may have been disappointed with our lack of grouping support, or the absense of the ability to render data by row rather than all at once. Or maybe you didn’t want to figure out how to deal with our rails plugin to use ActiveRecord in a camping project, or standalone. You might have also found our formatting system too brittle or our PDF support too weak.

Those things have changed. Come tell us what you think :)

Some links:

That should be enough shameless self promotion for now, but in all honesty, the overall improvements to Ruport have come through the support of our users, contributors and developers.

Also, Mike Milner is now churning about at much code as I am, and you can thank him for the revamp of our ActiveRecord support, which has finally made it’s way back into Ruport’s gem.

Looking forward to any and all feedback. If you’re on Freenode, you can usually catch up with us in #ruport, if you want to just chat informally.

Tim O

AddThis Social Bookmark Button

Via loudthinking.com, DHH points to the Magic Multi-Connections plugin by Nic Williams. This plugin could be used in any number of ways, Nic has a recipe for randomly selecting a connection from a pool, but the plugin could just as easily be made to work with a set of model objects spread across multiple databases.

The interesting story behind this is on DHH’s blog. Read: Alex Payne’s interview, then read David’s response, and finally the post from Sunday Scaling to multiple databases with Rails.

Update from Pat Eyler (12:15 PM Central):

http://glu.ttono.us/articles/2007/04/15/on-twitter-rails-and-community

Kevin makes some important points about how the community should/does respond to people pointing out things that RoR doesn’t do well. He also has a good analysis of the response Alex Payne’s interview and offers some ideas for how this conversation could have happened differently.

Gregory Brown

AddThis Social Bookmark Button

I spend most of my time building relatively large applications with Ruby, and this makes me forget how easy the quick and dirty hacks are. In less than the time it’d take me to google the right UNIX tool for escaping HTML, here is my tiny script that I use for things like blog entries and mass spam emails.

#!/usr/bin/env ruby

require "cgi"
puts CGI.escapeHTML(ARGF.read)

Mmh,… sweet simplicity. If you’ve not worked with the CGI lib before, there are probably other goodies in there so have a look at the API docs.

UPDATE: Sam Aaron does a good job of explaining what this script actually does in the comments

AddThis Social Bookmark Button

For the second year in a row, I have the privilege of being a Summer of Code mentor for Ruby Central, the US-based organisation responsible for the promotion of the Ruby language and the parent organisation for both the International Ruby Conference and the International Rails Conferences.

Gregory Brown

AddThis Social Bookmark Button

For those who saw my other post on what the RubyForge forum is about, I apologize for the redundancy here. However, I feel like perhaps if some folks pass this reminder along, it’ll get the message out. I’ve seen a huge resurgence of off topic posts, and I’m actually feeling bad that people end up waiting for replies only to get the same ‘we don’t deal with those questions here’ reply.

The RubyForge support forum is meant to support RubyForge itself. That means that if you have a feature request you might want to talk about before submitting a formal proposal, if you think you might have found a broken service in RubyForge, but you’re not sure, or if you just want to talk to us about some of the stuff we offer, you’ve found the right place.

If you have svn access that works on Windows but not on Linux, If you can’t install rails but you don’t suspect our gem servers are broken, or if you just want to ask what a particular library does, please, don’t use the RubyForge forum. You will get much better help elsewhere.

I am the only active volunteer monitoring our forum right now, so please… help me out a bit by using the great mailing lists out there!

This isn’t to discourage people from using our forum, in fact, if in doubt, post to us anyway. But please, read the FAQ before you post. If others can spread the word by linking my other article on what our forum is for, that’d be very helpful!

AddThis Social Bookmark Button

There is Ruby code no mortal being is meant to see, let alone use, for it is pure evil. If you wish to save your immortal soul, then read no further!

AddThis Social Bookmark Button

If you’re writing a C extension for Ruby, and you’ve got method that has optional arguments, be sure to use rb_scan_args(). Do not count argc. Read on if you want to know why.

Gregory Brown

AddThis Social Bookmark Button

Here’s a little problem I ran into in some old code of mine.

Sometimes we’ve got methods where we want to return a new instance of the same class.

It’s tempting to write the following code:

>> class A
>>   def a_whole_new_me
>>      A.new
>>   end
>> end

Sure enough, that seems to work:

>> a = A.new
>> a.class
=> A
>> a.a_whole_new_me.class
=> A

So what’s wrong with it? We forgot about subclasses!

>> class B < A; end
>> b = B.new
>> b.class
=> B
>> b.a_whole_new_me.class
=> A

If we’re expecting a copy of B and get A, this is certainly going to cause trouble, but the scary part is it might not right away (since B usually has all of A’s methods, but not necessarily the other way around)

Luckily, this is easy to fix, just use self.class

>> class A
>>   def a_whole_new_me
>>     self.class.new
>>   end
>> end
>> a = A.new
>> a.class
=> A
>> a.a_whole_new_me.class
=> A
>> class B < A; end
>> b = B.new
>> b.class
=> B
>> b.a_whole_new_me.class
=> B

This practice is usually a good idea whenever we want to refer to our class object. Rather than making things rigid, if you use self.class when possible, your code will be easier to extend and behave better in general. Of course, your mileage may vary depending on your task.