A Django site.
December 1, 2008

Pat Eyler
pate
On Ruby
» Ruby Refactoring Workbook Interview

I've recently heard that Bill Wake and Kevin Rutherford are working on a Ruby version of his excellent Refactoring Workbook. Bill and Kevin were kind enough to spend a little time with me talking about their upcoming book. First there was Design Patterns in Ruby, then a Ruby Edition of Refactoring, and now your reworking of Ruby Refactoring. What makes Ruby different enough to warrant these

November 28, 2008

Pat Eyler
pate
On Ruby
» Three Hours to Ruby

Hey, lazyweb, I need your help. I'm just about done teaching a series of classes on Bash scripting for the systems admins where I work (mostly junior types). I present a one hour course every other week, focusing on the basics that they'll be able put to use right away. Pretty soon, I'm going to start a series of similar courses about Ruby. Here's the rub though, I'm not sure where to start.

November 27, 2008

Pat Eyler
pate
On Ruby
» Ruby Best Practices: mini-Interview 1

In case you hadn't heard, O'Reilly has recently released Ruby Best Practices, by Gregory Brown, as a rough cut. This is one of those book that the Ruby community has been waiting for, even if we didn't know we were waiting for it. Not only is Gregory a great person to write a book like this, he's the kind of person who's going to make sure it does the most good for the community as a whole (

November 26, 2008

Pat Eyler
pate
On Ruby
» reek for Ruby rocks

I've been interested in developer tools for Ruby for a while now, and was pretty excited to find reek by Kevin Rutherford. After playing with reek a bit on a variety of code, I decided to ask Kevin a little more about it. Here's what we talked about. What prompted you to write reek? Kevin Lots of little nudges all occurred simultaneously and added up to one big push! In January 2008 I had

November 20, 2008

Hans Fugal
no nic
The Fugue :
» Feed Me

Our first frost should come any time now, and I want to have warning of it so we can rescue our tomatoes. Well, I have a link to the NWS Area Forecast Discussion in my bookmarks which I try to read every day, but some days I forget. What I need is a feed. But as far as I can tell only Honolulu is cool enough to get a feed for AFDs. Weird. So what I needed was to create a feed from an existing web page.

I thought I would find a website that offers a service like this but I didn't (in a few short minutes of searching). I found websites that came halfway, but they were very complicated to set up and/or they didn't display the body of the page, only a link. The whole point is that I want to read it in my feed reader!

So I whipped up this Ruby code (standard libs only, no gems required):

#! /usr/bin/ruby
require 'erb'
require 'open-uri'
require 'ostruct'

# configuration
channel = OpenStruct.new(:url => "http://www.srh.noaa.gov/data/EPZ/AFDEPZ",
                         :title => "EPZAFD",
                         :description => "National Weather Service Area Forecast Discussion, El Paso TX/Santa Teresa NM")
item = OpenStruct.new(:url => channel.url,
                      :title => "Area Forecast Discussion",
                      :date => Time.now)

# fetch the page
afd = open(item.url)
item.date = afd.last_modified unless afd.last_modified.nil?
item.body = "<pre>" + afd.read + "</pre>"

# emit
include ERB::Util
template = ERB.new <<EOF
Content-Type: application/rss+xml

<?xml version="1.0"?>
<rss version="2.0">
   <channel>
      <title><%= h channel.title %></title>
      <link><%= h channel.url %></link>
      <description><%= h channel.description %></description>
      <lastBuildDate><%= h Time.now.rfc822 %></lastBuildDate>
      <generator>feedme</generator>
      <item>
         <title><%= h item.title %></title>
         <description><%= h item.body %></description>
         <pubDate><%= h item.date.rfc822 %></pubDate>
         <guid><%= h "#{channel.url}?date=#{item.date.iso8601}" %></guid>
      </item>
   </channel>
</rss>
EOF
puts template.result(binding)

Nothing overly fancy here. I use open-uri to fetch the page, extract the Last-Modified header (if it exists) and shoehorn it into an ERB template for the RSS.

In this case I just made it executable and slapped a Content-Header before the output and call it as a CGI. You could just as well run a cron job to update a file on disk (In which case remove the Content-Header from the template).

Once I found the pure text version of the AFD, it was just a matter of slapping it between <pre> tags, but if you had some actual screen scraping to do you might want to look at Hpricot which makes that really easy. In particular, I could have used the URL http://www.crh.noaa.gov/product.php?site=NWS&issuedby=EPZ&product=AFD&format=txt&version=1&glossary=1 and done

...
require 'hpricot'
...
item.body = (doc/"#content").to_html

which is in fact how I started out. But this page doesn't have a Last-Modified header which means my feed reader would always show it as a new item (every time the cron job updated, or every time I hit the CGI script, either way). Luckily I found the text-only URL that doesn't have this problem.


Pat Eyler
pate
On Ruby
» Puppet and Ralsh

I wrote about puppet and how we're starting to look into it at work a couple of days ago. Yesterday, I learned about an awesome little tool that puppet provides — ralsh, the Ruby Abstraction Layer SHell. To understand just how cool ralsh is, you need to know a little bit more about how puppet works. puppet allows you to describe how a server should 'look' using a declarative language (this is

November 17, 2008

Hans Fugal
no nic
The Fugue :
» Clojure DSP Longing

I often find myself longing to be able to use Clojure, a very enticing lispy language that runs on the JVM.

I could possibly be using it right now in my dissertation research. It has the promise of dynamic languages, functional programming, almost-as-cool-as-Erlang concurrency, JVM performance, and Java library soup. It could be so awesome. A few months ago I started briefly down this road, unaware that…

Clojure sucks. Not generally, but it sucks for DSP. More specifically, Java and therefore Clojure has no real support for complex numbers. In order to do serious DSP, you need native syntactic, semantic, and performance support for complex numbers. Java has none of the above. Older versions of C didn't have syntactic or semantic support, but the performance of using arrays was plenty fast. Not so in Java, at least not to the extent necessary to override the lack of syntactic and semantic.

So someday, when I'm writing general purpose code again and not high performance DSP code, I will have an opportunity to use Clojure, and I think that will make me very happy. By then the book will be out of beta. The community will be in full swing. There will be awesome libraries. Children will play in pristine parks with formerly-ravenous ravens.

In the meantime, if anyone sees the scene change, do let me know.

November 13, 2008

Pat Eyler
pate
On Ruby
» Ruby's Pulling Puppet's Strings (and leading people to Ruby)

I've been trying to introduce Ruby at work for a long time, and have had some success here. I've been able to show many of the developers the value of Ruby, and it's made it's way into the organization as a valuable tool. I've never been able to make many inroads into the systems administration team that I work with though, and this has bothered me because I see myself as much more of a sys

November 11, 2008

Pat Eyler
pate
On Ruby
» Now that RubyConf 2008 is over ...

Ok, RubyConf 2008 is over (and I missed all the fun). Besides reading (or writing) about all the awesome presentations and the incredible hallway session, what should we be doing? Let me pitch two simple ideas that will help spread the joy that RubyConf brings. Come back to your local Ruby Brigade and share the wealth. Tell people what you learned and why it's important. Even better, start

September 5, 2008

Pat Eyler
pate
On Ruby
» New Improved MySQL library

MySQLPlus is a new, non-blocking MySQL driver for Ruby 1.8 and 1.9 (anyone know if it will run on Rubinius?) from eSpace, the folks who created NeverBlock. (They also talk about NeverBlockPG, a postgreSQL driver, but it seems to have been deleted.) To quote eSpace's announcement: [MySQLPlus does] IO operations concurrently and in a transparent manner, thanks to NeverBlock. An interesting side

June 11, 2008

Pat Eyler
pate
On Ruby
» Summer Conferences

There are two conferences that I’m not going to be able to go to this summer that I really wish I could find a way to swing: The Erlang eXchange which will be in London on June 26-27 and The Ruby Hoedown in Huntsville, Alabama on August 8-9. Erlang was a hot, swirling subcurrent at the 2008 MountainWest RubyConf. I get the feeling that there’s going to be a growing culture of cross-over

June 7, 2008

Pat Eyler
pate
On Ruby
» The Ruby Programming Language

I may not have posted recently, but I haven’t been completely away. Besides doing another 30 or so miles of hiking with my scouts (getting ready for a three day backpacking trip next weekend) and spending a lot of energy on my day job, I’ve also been spending some time with a couple of books. The first one that I want to tell you about is The Ruby Programming Language This reworking of the

May 9, 2008

Phil Windley
pjw
Phil Windley's Technometria
» Doing CPAN Installs Using Capistrano

I've been trying to use Capistrano for application deployment over the last few days, writing rules to do some common tasks, figuring out how it works, etc. One problem I ran into is that I have a private CPAN bundle that I use to ensure a machine has all the right Perl libraries when I deploy to it.

The problem is that CPAN is often run interactively and so module writers often assume the user will be present. That means that it stops in the middle and asks questions about skipping tests, etc. I searched for a while to figure out how to get a default answer to questions. It's not Capistrano's job and CPAN didn't seem to have a configuration option that worked. Turns out it's in MakeMaker.

MakeMaker is the Perl library that the CPAN modules use to automate the build process. There's an environment variable called PERL_MM_USE_DEFAULT that when true causes the MakeMaker prompt function to assume the default answer.

So, here's the task from the capfile I came up with.

task :load_bundle, roles => :local do
     run "cd /web/lib/perl/etc/kynetx-private-bundle; 
          sudo perl -MCPAN -e 
             '$ENV{PERL_MM_USE_DEFAULT}=1;
              install Bundle::kobj_modules'"
end

This works fine. Of course, you also need to make sure the account you're using for installs can sudo without a password or this will fail as well. Maybe there's a better way to do sudo inside Capistrano? I'd like to know about it.

Tags: kynetx sysadmin ruby perl

April 17, 2008

Pat Eyler
pate
On Ruby
» ruby > ( code == data )

In his Code Generation: The Safety Scissors Of Metaprogramming talk, Giles Bowkett talks about the power of Lisp and how Ruby approaches it. One of the Giles’ comparisons is that in Lisp (eq code data) which he translates into ruby as code == data. At the time, I just sort of went with the flow, but then I had a discussion with Mike Moore about SICP and I realized there’s a bit more to it than

April 10, 2008

Jesse Stay
obfuscated, Uncle_Jesse
Stay N' Alive » OSS
» Who Said Perl is Dead?

perl.pngI’ve been following the issue list for Google App Engine (just realized it doesn’t have an “s” in the official name), and the two top issues are a dead heat between Perl and Ruby in the requests to have Ruby or Perl support. Ruby, as of this writing is at 361 votes, and Perl is right on it’s tail at 347 votes. Perl until a few hours ago was pretty far ahead of Ruby. PHP is only at 70 votes, and Java is at 247 votes.

Does this mean Perl is making a comeback? Did we ever really leave Perl? As an avid Perl developer this makes me happy, as Perl can do anything Ruby or even Rails can do, and even more (Perl XS and tie-ins to C are very powerful!). All of my current Facebook Apps and OpenSocial Apps I do in Perl on an MVC Framework called Catalyst - it’s very scalable! It never made sense to me when people said that “Perl was Dead”. Is this just a reflection of the type of Audience Google supports, or is it reflective of what new media developers are actually developing in?

I’m hesitant in posting this, as it could bring more Ruby voters to the mix, but hey, let’s keep it fair. If you want to vote for Perl, click on the star here. If you want to vote for Ruby, click on the star here. Not a developer of either? Then you’re on your own. :-P

I wonder how Python would fare if it got equal treatment.

UPDATE: Within just a day after this post things have gone back to how I would expect them to be. Java has a strong lead over all the others, followed by PHP, then Ruby, then Perl. Perhaps the issues just needed a little exposure. Based on the interest, Perl is still far from dead though.

Share This

April 7, 2008

Hans Fugal
no nic
The Fugue :
» Grab Conference with Hpricot

So you slept through a few sessions of conference (or you were distracted by the computer or stuck in the bathroom with a potty training toddler). The natural thing to do is to listen to sessions one at a time on your mp3 player over the next week or two. But it would be too much work to go to the archives website every day to download the appropriate session, then sync your mp3 player. No, you need to download them all now. But clicking on each one is tedious at best.

Enter a script. Now I've done something like this in the past with just sed and grep, but this time I thought I'd skip the sed trial and error and practice some Hpricot. It was quick and painless:

require 'rubygems'
require 'hpricot'
require 'open-uri'
CONFERENCE_URL="http://www.lds.org/conference/sessions/display/0,5239,49-1-851,00.html"
doc = Hpricot(open(CONFERENCE_URL))
puts (doc/"a").map{|a| a['href']}.join("\n")

That little script extracts all the urls from a URL. Well maybe there's a program that does that already. Maybe it's urlview, but an impatient google didn't find it in time (and urlview isn't installed on my laptop). Now you continue on with the grep magic:

./strip_urls.rb | grep mp3 | grep -v Complete | xargs wget

And you're on your way.

March 27, 2008

Hans Fugal
no nic
The Fugue :
» Rails Sessions

I was doing some maintenance on my blog, and was devastated to find that Typo was taking 225 megabytes of resident RAM. Yikes! After some creative debug thinking and digging I figured out it was due to sessions. Typo now stores sessions in the database, so my maintenance cron job to delete old sessions didn't clean up old sessions. (Ha! had you going for a second!)

Well I could write a cron job to run a script to clean the sessions out of the db, like:

#!/bin/sh
sqlite3 /path/to/typo/db/production.db 'delete from sessions'

Ok, that's a bit extreme, but you get the idea. But when I deleted the sessions in this manner the memory usage didn't drop at all until I had restarted the server, which seems unnecessary. So instead I changed typo's configuration to use a different session store. I commented out this line in config/environment.rb:

-  config.action_controller.session_store = :active_record_store
+  #config.action_controller.session_store = :active_record_store

Then I restarted the server and fired up a browser. "Huh, that's odd… no sessions in tmp/sessions or /tmp or anywhere I can see. No, they're not in the database…" What I was seeing didn't match up with what all the stuff Google said. The default session store was PStore, aka file system, so they said. But apparently that recently changed in Rails, and now the default is CookieStore. From ActionController::Base documentation:

Sessions are stored in a browser cookie that‘s cryptographically signed, but unencrypted, by default. This prevents the user from tampering with the session but also allows him to see its contents.

Do not put secret information in session!

Well a quick grep -ri session app lib told me that typo wasn't storing anything secret, so I decided that default was alright with me. Now I don't have to set up any session cleanup script at all. Sweet.

Now, don't stop there. You should set your session key and secret while you're hanging out in config/environment.rb. Add the following lines in the same place as the line you commented out above:

config.action_controller.session['session_key'] = 'something unique'
config.action_controller.session['secret'] = 'get this from rake secret'

March 18, 2008

Pat Eyler
pate
On Ruby
» Announcements

Sorry I’ve not updated things in a bit, I’m hanging around the fringes of the flu and trying to play nurse for my family while they all suffer through it. In the meantime, I’ve let a lot of little things pile up and need to get them off my chest. First, I’m really excited by Gregory Brown’s new status as a Ruby Mendicant. Even better is that Ruby Central is going to match donations up to

March 13, 2008

Hans Fugal
no nic
The Fugue :
» Crème Rappel v2.2

I've released yet again. Go to the web page for the details. Now Crème Rappel has its own RSS feed so I'll shut up about here now.

» Crème Rappel v2

In the spirit of release early, rewrite often, I have released Crème Rappel version 2. Version 1 was a shell script that combined Growl and at. Then Apple released 10.5.2 not half a week later and broke at altogether. Sick of fighting with launchd and other Apple superiority complexes, I set about to nurture my own superiority complex and rewrite Crème Rappel to be completely independent of at.

Of course, that's getting too heavy for a shell script, so I moved to Ruby. One thing I didn't want was to require a daemon to be running. Daemons can fail or forget to start up, and that means I couldn't really truly trust the tool. The recent at debacle is just another case in point. So, instead I wrote Crème to fork a process that sleeps until the moment of truth, then fires off the reminder. It turns out the obvious function for the job, sleep(), is a poor choice here. In fact, every timer I tried had the same problem, including one I thought would not: setitimer(). When you suspend the laptop, it appears you also suspend time. If you don't believe me, try this simple experiment:

date; sleep 30; date

Put the laptop to sleep during the sleep for a substantial time, then notice that when you resume you still have to wait for the full 30 seconds to tick by even though it has actually been a minute plus since you issued the command. So I sleep for one second intervals instead, checking the time every time.

This is not just a backpedaling rewrite, though. It also adds more flexible and easy-to-type timespecs, and a spiffy website. If you give it a try and it doesn't work, or you struggle with the documentation, please do drop me a line so I can fix it. I want it to be worth every bit of bandwidth that you paid for it.

» Simple RSS

Have you ever thrown together a simple static webpage, only to find down the road that you want to add an RSS feed? What are your options? Maintain an ugly XML file by hand, or migrate to a big slow messy CMS. Yeah, no fun.

Sars is a simple RSS domain specific language. This:

# This is a YAML stream (http://yaml.org) but you don't need to know much YAML
# to get the hang of it.
# There are multiple "documents". The first document is the channel information:
---
title: Foo News Feed
link: http://example.com/foo/
description: News for the Foo Project
webmaster: you@example.com

# The second and subsequent documents are items. The first line is the title,
# the second line is the date, and the rest is the item description (Markdown).
# Because line endings are important, don't forget the pipe character.
--- |
Really Exciting Title
2/28/08 12:00
This is where I pontificate
about the really exciting fish
that is sitting on my plate.

Here's a [download link](http://example.com/foo/foo-1.0.tar.gz).

--- |
Another Item
2/28/08 12:04
You know, it doesn't really matter what order you put them in, since they each
have dates.

becomes this:

<?xml version="1.0"?>
<rss version="2.0">
<channel>
    <title>Foo News Feed</title>
    <link>http://example.com/foo/</link>
    <description>News for the Foo Project</description>
    <lastBuildDate>Thu, 28 Feb 2008 12:07:32 -0700</lastBuildDate>
    <generator>yaml2rss</generator>
    <webMaster></webMaster>

    <item>
        <title>Really Exciting Title</title>
        <description>&lt;p&gt;This is where I pontificate
about the really exciting fish
that is sitting on my plate.&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href=&quot;http://example.com/foo/foo-1.0.tar.gz&quot;&gt;download link&lt;/a&gt;.&lt;/p&gt;</description>
        <pubDate>Thu, 28 Feb 2008 12:00:00 -0700</pubDate>
        <guid>http://example.com/foo//2008-02-28T12:00:00-07:00</guid>
    </item>

    <item>
        <title>Another Item</title>
        <description>&lt;p&gt;You know, it doesn't really matter what order you put them in, since they each
have dates.&lt;/p&gt;</description>
        <pubDate>Thu, 28 Feb 2008 12:04:00 -0700</pubDate>
        <guid>http://example.com/foo//2008-02-28T12:04:00-07:00</guid>
    </item>

</channel>
</rss>

Any questions?

February 28, 2008

Hans Fugal
no nic
The Fugue :
» Simple RSS

Have you ever thrown together a simple static webpage, only to find down the road that you want to add an RSS feed? What are your options? Maintain an ugly XML file by hand, or migrate to a big slow messy CMS. Yeah, no fun.

Sars is a simple RSS domain specific language. This:

# This is a YAML stream (http://yaml.org) but you don't need to know much YAML
# to get the hang of it.
# There are multiple "documents". The first document is the channel information:
---
title: Foo News Feed
link: http://example.com/foo/
description: News for the Foo Project
webmaster: you@example.com

# The second and subsequent documents are items. The first line is the title,
# the second line is the date, and the rest is the item description (Markdown).
# Because line endings are important, don't forget the pipe character.
--- |
Really Exciting Title
2/28/08 12:00
This is where I pontificate
about the really exciting fish
that is sitting on my plate.

Here's a [download link](http://example.com/foo/foo-1.0.tar.gz).

--- |
Another Item
2/28/08 12:04
You know, it doesn't really matter what order you put them in, since they each
have dates.

becomes this:

<?xml version="1.0"?>
<rss version="2.0">
<channel>
    <title>Foo News Feed</title>
    <link>http://example.com/foo/</link>
    <description>News for the Foo Project</description>
    <lastBuildDate>Thu, 28 Feb 2008 12:07:32 -0700</lastBuildDate>
    <generator>yaml2rss</generator>
    <webMaster></webMaster>

    <item>
        <title>Really Exciting Title</title>
        <description>&lt;p&gt;This is where I pontificate
about the really exciting fish
that is sitting on my plate.&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href=&quot;http://example.com/foo/foo-1.0.tar.gz&quot;&gt;download link&lt;/a&gt;.&lt;/p&gt;</description>
        <pubDate>Thu, 28 Feb 2008 12:00:00 -0700</pubDate>
        <guid>http://example.com/foo//2008-02-28T12:00:00-07:00</guid>
    </item>

    <item>
        <title>Another Item</title>
        <description>&lt;p&gt;You know, it doesn't really matter what order you put them in, since they each
have dates.&lt;/p&gt;</description>
        <pubDate>Thu, 28 Feb 2008 12:04:00 -0700</pubDate>
        <guid>http://example.com/foo//2008-02-28T12:04:00-07:00</guid>
    </item>

</channel>
</rss>

Any questions?

» Crème Rappel v2.2

I've released yet again. Go to the web page for the details. Now Crème Rappel has its own RSS feed so I'll shut up about here now.

February 22, 2008

Hans Fugal
no nic
The Fugue :
» Crème Rappel v2

In the spirit of release early, rewrite often, I have released Crème Rappel version 2. Version 1 was a shell script that combined Growl and at. Then Apple released 10.5.2 not half a week later and broke at altogether. Sick of fighting with launchd and other Apple superiority complexes, I set about to nurture my own superiority complex and rewrite Crème Rappel to be completely independent of at.

Of course, that's getting too heavy for a shell script, so I moved to Ruby. One thing I didn't want was to require a daemon to be running. Daemons can fail or forget to start up, and that means I couldn't really truly trust the tool. The recent at debacle is just another case in point. So, instead I wrote Crème to fork a process that sleeps until the moment of truth, then fires off the reminder. It turns out the obvious function for the job, sleep(), is a poor choice here. In fact, every timer I tried had the same problem, including one I thought would not: setitimer(). When you suspend the laptop, it appears you also suspend time. If you don't believe me, try this simple experiment:

date; sleep 30; date

Put the laptop to sleep during the sleep for a substantial time, then notice that when you resume you still have to wait for the full 30 seconds to tick by even though it has actually been a minute plus since you issued the command. So I sleep for one second intervals instead, checking the time every time.

This is not just a backpedaling rewrite, though. It also adds more flexible and easy-to-type timespecs, and a spiffy website. If you give it a try and it doesn't work, or you struggle with the documentation, please do drop me a line so I can fix it. I want it to be worth every bit of bandwidth that you paid for it.

February 12, 2008

Pat Eyler
pate
On Ruby
» Book Review: Pulling Strings with Puppet

Puppet is a great looking configuration management tool written in Ruby, from Luke Kanies at Reductive Labs. Recently, James Turnbull has written a book, Pulling Strings with Puppet, about it. I’ve interviewed both Luke and James about Ruby, Puppet, and James’ book. So, it’s only fair that I turn an eye to the book as well. In the interest of full disclosure I should mention that Apress

February 11, 2008

Pat Eyler
pate
On Ruby
» Puppet Interview with James Turnbull

Recently, I’ve been reading about Puppet because of James Turnbull’s excellent Pulling Strings with Puppet. James has been good enough to do a short interview with me as well. I hope you enjoy reading it as much as I enjoyed chatting with James (you might want to check out my interview with Luke Kanies too). I normally think of you as a Pythonista, yet Puppet comes from the land of Ruby.

January 29, 2008

Pat Eyler
pate
On Ruby
» Ruby Concurrency with Actors

Tony Arcieri (read an interview with Tony here) recently posted an announcement about his new Revactor library, which provides actor style concurrency built atop Ruby 1.9’s new Fiber technology. Since Fibers and Actors haven’t been a part of the Ruby lexicon, I wanted to put some information together to help myself (and anyone else who wants to crib off my notes) get up to speed. To start

» Interview With Revactor Developer Tony Arcieri

With the recent release of his Revactor library, I wanted to talk with Tony Arcieri about Ruby, Actors, and Revactor. He was kind enough to sit down for a short interview. Here’s what we talked about. How did you get started with Ruby? Tony Ruby is a language some roommates of mine were using for years and kept raving to me about. Unfortunately, I was a performance-obsessed C programmer

January 25, 2008

Pat Eyler
pate
On Ruby
» MWRC mini-interview: Patrick Farley

Here’s another mini-interview to whet your MWRC appetite. I asked Patrick Farley of ThoughtWorks about his talk and which MWRC sessions he’s excited about. With speakers like this, how could you not register—$100 bucks for two days of Ruby awesomeness is an incredible deal. Your session is entitled “Ruby Internals”, why should people be excited to come see it? Programming in Ruby leads

January 23, 2008

Pat Eyler
pate
On Ruby
» RubyZone, RailsSpace, and Ruby DVDs

dZone has recently introduced a set of ‘zones’ with original content, forums, and other things about specific topics to compliment their social bookmarking site. One of these is the RubyZone. I’ve been asked to work as a ‘Zone Leader’ there, writing new material and helping build the community. Even before I’d gotten there someone else had written some material, a review of the book RailsSpace

January 16, 2008

Phil Windley
pjw
Phil Windley's Technometria
» Scheme and Ruby

Duane Johnson pointed me to a very interesting discussion on Y Combinator about the differences between Scheme and Ruby. This is an excellent discussion--not a flame war--that I found enlightening. The summary, if you don't want to read the discussion thread:

  • Ruby closures are more complex
  • Macros, macros, macros...

Can't say enough about macros. Every language besides Lisp and it's close relatives trade macros for complex syntax. Maybe that's a good trade-off, maybe not. Nevertheless, it is a trade-off. You can't have the full power of macros without simple (abstract) syntax that's exposed to the programmer.

Now, that I've said that, I wonder if IO's impressive reflection can do the same. Someone more enlightened than I tell me: what can't be done with reflection that can be done with macros?

I do believe that using reflection is more complex than using macros. It reminds me of poking a stick in a black box to flip a switch.

Tags: programming cs330 scheme ruby


Von Fugal
no nic
ATOM von Fugal
» Some _Times_ You Just Want _Things_

Working on an AES implementation in ruby, I’ve had many occasion to do:

n.times {|i| some calculations based on i}

I’m sure many of you have used the Integer#times method much to your glee. I’m sure many of you have also had the occasion where you realize that you want those resultant calculations to end up in an array of some sort. At this point you have two options: create an array before hand and << those results in, or change your iterator to (0...n).map {|i| ...}. Both options are severely lacking in taste, IMO. So I came up with a third option. Enter Integer#things.

ary = n.things {|i| ...}

Notice how the syntax here remains consistent with the semantics. Before you wanted to do something n times. Here you want the same, but you want to store the results, you want n results, or n things.

Don’t get me wrong, I love Range and it certainly has it’s place. I would never argue that 26.things { make a letter } is a better approach than ('a'..'z') { just have your letter already }. Like I said, it’s about semantics, do you really want that range or is it more about the number of things? And as we all know deep down, the syntactics should match the semantics wherever possible.

So here is my implementation for Integer#things and I really hope something like this becomes included in future ruby.

                  class Integer
                    def things &b
                      b ||= proc {|i| i}
                      ary = []
                      times do |i|
                        ary << yield(i)
                      end
                      ary
                    end
                  end
                  
0 comments

January 10, 2008

Pat Eyler
pate
On Ruby
» Sequel Interview with Sharon Rosner

With the recent release of Sequel, I took some time to interview Sharon Rosner about it. Sequel is a really cool project, and uses some Ruby tools in novel ways. Read on and find out more. There are already several ORMs out there. Why write another one? Sharon I wrote Sequel mainly because I tried ActiveRecord and it really didn’t fit what I wanted to do. The first thing that frustrated

January 2, 2008

Jesse Stay
obfuscated, Uncle_Jesse
Stay N' Alive » OSS
» Perl - NOW is the Time to Step Up!!!

Rails has finally done it! They have finally admitted what we as Perl programmers have said since people went all Ga-Ga over it around the launch of BaseCamp. In an unprecedented blog post, Zed Shaw, creator of Mongrel, totally turned his back on the Rails community, saying what I’ve heard in outside circles all along (from Zed himself):

“This is exactly what makes Rails a ghetto. A bunch of half-trained former PHP morons who never bother to sit down and really learn the computer science they were too good to study in college. “

Perl is at a prime spot to step in here - this year, John Rockway published the first book on Catalyst, Perl’s answer to Ruby on Rails, in a much more Robust, more scalable package. Catalyst is stronger than ever. You see, I know some of the writers of Catalyst, and I know for a fact there is an entirely different mentality than that of Rails - Catalyst was built by Computer Scientists, and therefore was built by people who understand how an MVC architecture should be built!

My message to the Perl community is this - step in, do something! Promote the heck out of Catalyst now. Blog about it! Pull Zed aside, show him how it can help him, get him to blog about it. Ruby on Rails is weak right now, it’s breaking apart from the inside. Now is the time for the Perl community to show its strength and unite in an effort to make Perl once again the most used platform on the web! We need some big names in the Perl community to be stepping in here and taking advantage of the attention Zed’s bringing to Rails.

, , , , , , , , , , , , ,

Share this article with a friend...

Gregarious FeedFlare

December 26, 2007

Pat Eyler
pate
On Ruby
» Real World Performance On Boxing Day

Well, Ruby 1.9.0 landed yesterday, as expected. I’d be remiss if I didn’t start out by thanking matz, ko1, and all the other hackers involved in getting this milestone release out the door. It’s a great step for Ruby, and one that we’ve been waiting a long time for. The bad news is that 1.9.0 is just a development release branch leading up to 2.0, and it doesn’t yet run Rails or Mongrel.

January 22, 2008

Pat Eyler
pate
On Ruby
» Design Patterns In Ruby, a review

UPDATE: If you like this review, and want to learn more, check out interview with author, Russ Olsen. The Professional Ruby Series from Addison-Wesley is rapidly becoming a heavyweight in Ruby book circles. I just received a complimentary copy of Russ Olsen’s Design Patterns In Ruby from them, and it looks like a great addition to their, already solid, line-up of books. Russ breaks the

December 18, 2007

Pat Eyler
pate
On Ruby
» Interview with Topher Cyll, Author of Practical Ruby Projects

Topher Cyll, author of Practical Ruby Projects and I have traded a couple of emails since his book was released by Apress. Here's what we talked about: What makes a Ruby project ‘practical’? Topher Good question! I think the first requirement for a “practical project” is that you actually want to do it! Whether you do it for work, enjoyment, or just to learn doesn’t really mater. All the

December 13, 2007

Pat Eyler
pate
On Ruby
» Philippe Hanrigou Interview (and more troubleshooting hints)

I reviewed ‘Troubleshooting Ruby Processes’ last week. Since I really liked it, I decided to take a little bit of time to talk to Philippe about it. Fortunately, he was gracious enough to answer my questions. If you’d like to grab a copy of his shortcut for yourself, you can buy one here. Philippe passed along a bunch of great hints and links that aren’t in his book, but you can read them all

December 10, 2007

Pat Eyler
pate
On Ruby
» Ruby Dev Tools Survey Results

From the results of my Ruby developer tools survey, it looks like there are three real tiers of tools that a lot of people are using: The big guys: Test Unit (53%), RSpec (50%), and rcov (47%) The middle tier: autotest (38%), and ruby-debug (32%) Everyone else: ruby-prof (17%), heckle (6%), and dcov (2%) The only surprise in the top tier is that RSpec has already captured as much

December 5, 2007

Pat Eyler
pate
On Ruby
» Troubleshooting Ruby Processes

Philippe Hanrigou has written an excellent ‘shortcut’ for Addison-Wesley’s Professional Ruby Series. This is a really different kind of Ruby book, and one that’s long overdue. Troubleshooting Ruby Processes takes a quick look at some of the Rubyland tools that developers can use to find problems, then dives into three (unix) system tools that aren’t as well known (or used) as they should

December 4, 2007

Pat Eyler
pate
On Ruby
» NetBeans 6.0: Interview with Tor Norbye

I just saw the news the NetBeans 6.0 is out, featuring some great Ruby and Rails support. Tor Norbye and the rest of the NetBeans crew deserve some major kudos for all their work. Tor was nice enough to take a couple of minutes to answer some questions about Ruby and NetBeans for me. So, here goes— Why should Ruby/Rails folks who are busily hacking away in emacs/vi/textmate/whatever take

December 3, 2007

Von Fugal
no nic
ATOM von Fugal
» Rails :memory: revisited

As I was creating a new rails app, I used this previous post of mine to set up the in memory database. Well it’s time for an update. Apparently now the rails config/environments/*.rb are run in the context of Rails::Initializer. So instead of creating that context as in the previous post, you simply do:

        alias initialize_database_old initialize_database
        def initialize_database *args
          initialize_database_old
          load "#{RAILS_ROOT}/db/schema.rb" 
        end
0 comments

November 28, 2007

Pat Eyler
pate
On Ruby
» Holiday Blogging Contest

It’s been a while since I’ve run a blogging contest here but, just in time for the holidays, I’ve teamed up with Apress to run another one. Earlier this month, they released Practical Rails Projects, and in December, they’ll be publishing Practical Ruby Projects. The idea of ‘practical projects’ sounded like a great topic for blogging, and the folks over at Apress agreed. So

November 5, 2007

Hans Fugal
no nic
The Fugue :
» X-Sendfile

I'm writing a little photo gallery of my own, because everything out there stinks. But sending big images files in Rails (using send_file and send_data) is slow, mostly because you tie up a whole rails process just feeding data to the web. Web servers like Apache, Lighttpd, and Mongrel are good at serving static files, let them do it.

That's the idea behind X-Sendfile. If you send an X-Sendfile header with the path of the file you want to send, then a supporting webserver will do the dirty work and do it fast, and you can get on with serving other requests.

That's the theory anyway, but there's some bumps in the road. First, AFAICT mongrel doesn't support X-Sendfile. This is fine when mongrel is running behind an Apache proxy which does, but kind of throws a wet blanket on development and apachephobes like myself. Ok, apachephobe might be a bit strong, but I don't want to set that monster on my laptop just for some rails development. So mongrel's out. Correct me if I'm wrong.

Lighttpd supposedly invented X-Sendfile, but 1.4.x and earlier don't seem to support it. Instead, you have to use the header X-LIGHTTPD-send-file. Also, it doesn't work unless Content-Length is properly set (or perhaps if it's absent). This is bad news for rails users, since a bug in rails causes the Content-Length header to be set to the content, which is not the file. If you do render :nothing => true, then the content is one space character, and the Content-Length is 1, and Lighttpd defiantly refuses to fix it. So you either have to work around the rails bug, or upgrade to lighttpd version 1.5.x (now in release candidate) which supposedly works (I haven't tested it—I can't get it to compile on Leopard). I say bug in rails, but frankly I'm more inclined to consider this bad behavior on the part of lighttpd. In that vein, here is a patch for lighttpd version 1.4.18 that will enable both X-LIGHTTPD-send-file and X-Sendfile headers with rails 1.2.3 which has the Content-Length resetting behavior. It makes lighttpd set the Content-Length on its own. Thanks to stbuehler for the patch.

--- src/mod_fastcgi.c.orig      2007-11-05 13:52:47.000000000 -0700
+++ src/mod_fastcgi.c   2007-11-05 13:55:17.000000000 -0700
@@ -2530,22 +2530,28 @@
                }

                if (host->allow_xsendfile &&
-                                   NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file"))) {
+                                   ((NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-LIGHTTPD-send-file")))
+                                     || (NULL != (ds = (data_string *) array_get_element(con->response.headers, "X-Sendfile"))))) {
                    stat_cache_entry *sce;

                                         if (HANDLER_ERROR != stat_cache_get_entry(srv, con, ds->value, &sce)) {
-                                               /* found */
-                                                con->parsed_response &= ~HTTP_CONTENT_LENGTH;
-
+                                               data_string *dcls = data_string_init();
+                                                /* found */
                        http_chunk_append_file(srv, con, ds->value, 0, sce->st.st_size);
                        hctx->send_content_body = 0; /* ignore the content */
                        joblist_append(srv, con);
-                                       }
-                                        else
-                                        {
-                                               log_error_write(srv, __FILE__, __LINE__, "sb",
-                                                       "send-file error: couldn't get stat_cache entry for:",
-                                                       ds->value);
+
+                                               buffer_copy_string_len(dcls->key, "Content-Length", sizeof("Content-Length")-1);
+                                               buffer_copy_long(dcls->value, sce->st.st_size);
+                                               dcls = (data_string*) array_replace(con->response.headers, (data_unset *)dcls);
+                                               if (dcls) dcls->free((data_unset*)dcls);
+
+                                               con->parsed_response |= HTTP_CONTENT_LENGTH;
+                                               con->response.content_length = sce->st.st_size;
+                                       } else {
+                                               log_error_write(srv, __FILE__, __LINE__, "sb",
+                                                       "send-file error: couldn't get stat_cache entry for:",
+                                                       ds->value);
                                         }
                }
--- src/response.c.orig 2007-11-05 14:08:26.000000000 -0700
+++ src/response.c      2007-11-05 14:04:49.000000000 -0700
@@ -59,7 +59,8 @@
    ds = (data_string *)con->response.headers->data[i];

    if (ds->value->used && ds->key->used &&
-                   0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1)) {
+                   0 != strncmp(ds->key->ptr, "X-LIGHTTPD-", sizeof("X-LIGHTTPD-") - 1) &&
+                   0 != strncmp(ds->key->ptr, "X-Sendfile", sizeof("X-Sendfile") - 1)) {
            if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Date"))) have_date = 1;
            if (buffer_is_equal_string(ds->key, CONST_STR_LEN("Server"))) have_server = 1;

Then, you need to configure your lighttpd server. Run script/server lighttpd once to generate config/lighttpd.conf, and add this bit to the fastcgi.server section:

    "allow-x-send-file" => "enable"

Finally, use it—either by setting the X-Sendfile header manually or by using the rails x_send_file plugin (I recommend the latter).

Here's some links for more reading:

November 3, 2007

Hans Fugal
no nic
The Fugue :
» Backticks 2.0

When you've been bitten by spaces and other odd characters in filenames as often as I have, you begin to get not a little bit paranoid. Beginners often make this mistake (ruby syntax, but the same thing happens in bash, perl, python, etc.):

foo = `file #{filename}`

They quickly learn to do this instead:

foo = `file "#{filename}"`

This works fine until they come across a filename with quotes or any other characters that are special to the shell from within quotes.

What's needed is something akin to what can be done with exec and system. With those two, you can do something like this and it doesn't matter what crazy filename is thrown at it, you won't have any trouble:

system 'file', filename

But exec and system don't return stdout, like backticks do. The former doesn't return at all, and the latter returns the return value. Here is an idiom that works like glorified array-parameter backticks in ruby:

def backtick(cmd,*args)
  IO.popen('-') {|f| f ? f.read : exec(cmd,*args)}
end

Everything you need to understand that code can be found in ri IO.popen and ri Kernel.exec. If you can think of a better name than backtick do let me know. Now our code becomes paranoid-friendly:

foo = backtick('file',filename)

While we're on the subject, a very handy method is Open3#popen3, which is a bit overkill for this glorified backticks problem but could very well simplify your life (or mine) in the future.

October 30, 2007

Phil Windley
pjw
Phil Windley's Technometria
» Barx: A Proxy Resolver for XRI

Victor Grey and Kermit Snelson have created an XRI proxy resolver in Ruby called Barx. In it's most simple form, a proxy resolver returns an XRDS document when given an XRI. From the spec: "Proxy resolvers enable applications even those that do not natively understand XRIs but can process HTTP URIs---to easily access the functions of an XRI resolver remotely." An example is xri.net. Barx implements the entire XRI resolution spec with the exception of SAML trusted resolution.

According to Victor, "[t]he proxy resolver is a fast HTTP server based on Mongrel and Merb that can be run as a local service (on localhost:someport) to provide XRI resolution and caching for other applications such as OpenID relying parties, or as a scalable public service if desired." The Ruby gem can be installed with

gem install barx

and the proxy can be downloaded from Rubyforge.

Tags: xri identity ruby

October 16, 2007

Pat Eyler
pate
On Ruby
» SICP 1.1.6 (Ruby) A look back

In my post on SICP 1.1.6, there were a couple of questions raised about my Ruby code. Fabio Akita Your first example would be better written off as: def abs(num) num < 0 ? -num : num end Personally, I really hate the ternary if, I’ve always thought that it makes code harder to read. It’s probably still worth looking at though, since my biases are just that. Peter Cooper ... I was just

October 11, 2007

Stephen Shaw
no nic
Decriptor's Blog
» Graphically display your log files

glTail.rb is a really cool app for displaying your log files graphically using opengl. I finally decided to download it this evening and give it a try. Its really easy to setup, so minimal effort required. All you have to do is install a couple common packages, mod the script just a little, and run it.  This project was started only 4 days ago and has had several new things added.

I have it running against two of my web sites and it looks really cool. I don’t get tons of traffic so mine isn’t as cool as the video clip on the website, but cool none the less. The one thing that I wish it had was a the ability to parse mysql log files. I don’t know ruby, but might look at it anyways.

October 8, 2007

Pat Eyler
pate
On Ruby
» Reading SICP 1.1.6

This time around, I’ve decided to toss the translations for Ruby, Factor, and Erlang into the same post instead of trying to juggle multiple posts and point them all at one another. So, without further ado … Section 1.1.6 Let’s take a look at section 1.1.6, the goal of this section is to look at conditional expressions through implementing an absolute value procedure. the book iterates

October 3, 2007

Pat Eyler
pate
On Ruby
» Reading SICP in Ruby: 1.1.4

Recently, I posted about reading and working through SICP in languages other than scheme. Today is the day that I start. I don’t know how quickly I’ll work through things, but we’ll see what I can do. In addition to Ruby, I’m also hoping to work with Factor and Erlang in parallel. My first SICP post is nice and easy, I’m skipping up to Section 1.1.4 of SICP which covers

September 21, 2007

Phil Windley
pjw
Phil Windley's Technometria
» Installing Rails on Fedora

I'm building a virtual machine (VMWare flavor) for use with Rails development. After installing Fedora, there were a few things I had to do to get everything ready. I thought I'd take a minute and document them in one play for the next poor soul.

First, I don't know what I do wrong, but the GUI auto-update feature seems more trouble than it's worth. I like doing it manually. So the first thing to do is:

sudo /usr/bin/yum -y update

I've found that the Yum system can get corrupted and hang (I think I do this by force quitting the auto-update tool). Alternantely, you might see a bunch of errors. To fix that, I do the following:

sudo rm -f /var/lib/rpm/__db.*
sudo rpm --rebuilddb

Next, I install or update some other tools:

sudo /usr/bin/yum -y install \
sudo \
wget \
tar \
gzip \
make \
gcc \
mysql \
mysql-devel \
mysql-server \
ruby \
ruby-libs \
ruby-mode \
ruby-rdoc \
ruby-irb \
ruby-ri \
ruby-docs \
ruby-devel \
ruby-mysql \
rubygems \
subversion \
lighttpd \
lighttpd-fastcgi \
httpd \
ImageMagick \ 
ImageMagick-devel

Now, we're ready to install rails and some other gems:

sudo gem install rails --include-dependencies
sudo gem install rmagick

If gem complains about "Could not find rails..." you need to reset the gem cache. The correct path can be found using the command gem env.

sudo rm -rf /usr/lib/ruby/gems/1.8/source_cache
sudo gem update

If you're going to use MySQL, be sure to set it to start up and set a root password:

sudo /sbin/chkconfig mysqld on

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h localhost.localdomain password 'new-password'

If you're going to use FastCGI with LightTPD, then you'll need to install the FastCGI code:

curl -O http://www.fastcgi.com/dist/fcgi-2.4.0.tar.gz
tar xzvf fcgi-2.4.0.tar.gz
cd fcgi-2.4.0
./configure --prefix=/usr/local
make
sudo make install
cd ..

And the Ruby FastCGI support:

curl -O http://rubyforge.iasi.roedu.net/files/fcgi/ruby-fcgi-0.8.7.tar.gz
tar xzvf ruby-fcgi-0.8.7.tar.gz
cd ruby-fcgi-0.8.7
ruby install.rb config --prefix=/usr/local
ruby install.rb setup
sudo ruby install.rb install
cd ..

And the fcgi gem:

sudo gem install fcgi

I also need RMagick (the Ruby ImageMagick package) installed. Notice that I installed ImageMagick in the yum command above. To install RMagick, I used the gem install:

sudo gem install rmagick

Note that the ImageMagick install I got from yum had been built with the configuration option for TrueType fonts, so it was looking for those and failing. You can see what fonts your installation is looking for using the convert command:

convert -list type

You'll see path information for the configuration files as well as the various fonts each type file is loading. I changed my type-windows.xml file to look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE typemap [
  <!ELEMENT typemap (type+)>
  <!ELEMENT type (#PCDATA)>
  <!ELEMENT include (#PCDATA)>
  <!ATTLIST type name CDATA #REQUIRED>
  <!ATTLIST type fullname CDATA #IMPLIED>
  <!ATTLIST type family CDATA #IMPLIED>
  <!ATTLIST type foundry CDATA #IMPLIED>
  <!ATTLIST type weight CDATA #IMPLIED>
  <!ATTLIST type style CDATA #IMPLIED>
  <!ATTLIST type stretch CDATA #IMPLIED>
  <!ATTLIST type format CDATA #IMPLIED>
  <!ATTLIST type metrics CDATA #IMPLIED>
  <!ATTLIST type glyphs CDATA #REQUIRED>
  <!ATTLIST type version CDATA #IMPLIED>
  <!ATTLIST include file CDATA #REQUIRED>
]>
<typemap>
</typemap>

This did the job, but beware that it may break other things you want to use ImageMagick for. I just know it worked for what I wanted to do.

Finally there are a few small jobs.

  • Add /usr/local/lib to /etc/ld.so.conf and run /sbin/ldconfig.
  • Add a alias for root to /etc/aliases. Don't forget to run newaliases.
  • Set up hostname. I like to edit /etc/sysconfig/network directly, but that's OS specific.
  • Set up any users. Be sure to set passwords.
  • Run chkconfig --list |more and turn off anything you don't need. I usually turn off bluetooth, cups, and yum-updatesd for starters. Turn on anything you do (like mysqld).
  • Set up /etc/sudoers. I can't tell you what to do since that's specific to what you are setting up. The simplest configuration is to use set it up so that anyone in group wheel can be a sudoer. Then add the wheel group to each user who should be able to sudo.

At this point, I'm unsure that the FastCGI is working completely with LightTPD. I'll add more information if something changes.

Tags: linux howto rails ruby

September 5, 2007

Pat Eyler
pate
On Ruby
» Book Review: Practical Ruby for System Administration

Apress has been putting out a number of solid Ruby books of late, and Practical Ruby for System Administration by André Ben Hamou is one of two great additions to their catalog. André has a easy to read writing style, and covers a lot of ground in this book. The book contains a number of good examples, and would make a great book for a sys admin who’s looking into Ruby.

September 4, 2007

Hans Fugal
no nic
The Fugue :
» QtRuby Arrives

I've extolled the virtues of QtRuby before. As GUI toolkits go, Qt is the best (IMHO) and as languages go Ruby is tops (again, IMHO), so naturally QtRuby has potential. QtRuby's biggest stumbling block in the past has been installation. Easy on Linux, but deep voodoo on OS X and perhaps even worse in Windows. That has finally changed.

qt4-qtruby now uses a cmake-based build system. I installed Qt4 from source on my MacBook, then followed the instructions to install qt4-qtruby and gave it a spin. Everything worked perfectly out of the box.

I can't speak for Windows, but QtRuby on Linux and OS X is now practical. (It has been since June or perhaps earlier, but I just got around to trying it out.) Celebrate!

August 20, 2007

Hans Fugal
no nic
The Fugue :
» Camping XHTML

I have a little Camping toy, and I decided to play a bit with MathML to render a few simple equations. I read the insructions and played around with a static file and found that all I needed was to use XHTML and everything would Just Work™.

Until I tried to do it in Camping. I'll spare you the boring details and cut to the chase:

def layout
  @headers['Content-Type'] = 'application/xhtml+xml'
  xhtml_transitional do
    body { self << yield }
  end
end

The trick is getting the MIME type right.

August 10, 2007

Von Fugal
no nic
ATOM von Fugal
» Rails and SQLite3: Default Values

Here’s another rails fix. This one is for SQLite3 >= 3.3.8. SQLite decided to return sql strings for the default values shown in table definitions. This broke rails, the rails people got mad and won’t introduce a workaround. Well here’s my workaround.

sqlite_fix.rb:
module ActiveRecord
          module ConnectionAdapters
            class SQLiteAdapter < AbstractAdapter
              def columns table_name, name=nil
                table_structure(table_name).map do |field|
                  /^'?(.*)'?$/.match field['dflt_value']
                  field['dflt_value'] = $1
                  SQLiteColumn.new(field['name'], field['dflt_value'], field['type'], field['notnull'] == "0")
                end
              end
            end
          end
        end
Include it at the end of environment.rb. That’s it! 0 comments

August 5, 2007

Von Fugal
no nic
ATOM von Fugal
» Rails :memory: testing in SqLite

I wanted to get that nifty :memory: db thing working for the test database in Rails. There are a sparse few articles floating around telling you how to do this. All of them, IMHO, are kinda ugly, or at least not-so-elegant. Here’s my answer, which took a lot of digging around in the inner workings of rails to come by.

First, do what everyone else tells you, put this in your config/database.yml:
        test:
          adapter: sqlite3
          database: ":memory:" 
        
Once you got that, you have to have some way of loading the schema into your memory db every time you run the test. I found that the best place to do this is in config/environments/test.rb. If you have an even better place, please let me know. At first I thought I could just load "#{RAILS_ROOT}/db/schema.rb" and be done with it. Alas, at this point there is no established connection to the db. So we have to modify things in such a way that this cute little command will get run just after establishing the db connection, but before the db is accessed. I did it like so:
        module Rails
          class Initializer
            alias initialize_database_old initialize_database
            def initialize_database
              initialize_database_old
              load "#{RAILS_ROOT}/db/schema.rb" 
            end
          end
        end
        
Then don’t forget to rake db:schema:dump before running rake test.

There’s probably other things you could do, like use ActiveRecord::Base.establish_connection instead of Initializer.initialize_database.

I break the above code block into lib/memdb.rb and simply require that inside of config/environments/test.rb. I tried to just add a metaclass to the config variable you see in test.rb but that is apparently some kind of impostor, because it didn’t work. Anyway, armed with this knowledge someone could probably make a pretty sane plugin to cleanly bring you :memory: testing.

0 comments

August 1, 2007
» Does Oracle really love Rails?

If one searched for Oracle and Rails they're bound to turn up a bunch of results that appear to indicate that Oracle is on the Rails bandwagon. How Web2.0 of them. (I'm trying to think of some funny snide remark about a rails acquisition, but can't

June 30, 2007

Pat Eyler
pate
On Ruby
» rocaml interview leftovers

I put together a mini-interview with Mauricio Fernandez about his new Ruby/OCaml bridge, rocaml. You can read most of it over at Linux Journal, but here’s a little bit that did