So.

Is it as fun as it used to be?

Archive for the ‘Ruby’ Category

Toronto Lisp Meetup

There’s going to be another attempt at a lisp user meetup in Toronto:

The Announcement

This has been tried at least once already, but it fizzled out.

The meetup is open to anybody interested in lisp, not just people using lisp. So if you’re curious…

Unfortunately for me, I won’t be able to make it this time (I’m supposed to be in Waterloo that evening, so at least now there’s an upside should there be a winter storm :-)

Advertisements

Written by hutch

December 13, 2007 at 7:40 am

Posted in Lisp, Ruby

A Little Unnecessary Smalltalk Envy

In A Little Head Trauma…: Returning None is Evil, Mark Derricutt provoked a brief moment of Smalltalk envy.


(self doSomethingThatMightReturnNil)
  ifNotNil: [val | val doSomethingWithNoHassle].

In addition to what Mark was actually responding to, it is an annoyance that I’ve had repeatedly in Ruby but never really considered fixing. Until now.

The annoying code:


tmp = doSomethingThatMightReturnNil
tmp.doSomethingWithNoHassle if tmp

Just look at those tmp variables.

This is the ‘cure’:


class Object
  def if_not_nil(&blk)
    yield(self) if blk
  end
end

class NilClass
  def if_not_nil(&blk)
  end
end

I like monkey patching.

And now I can write:


doSomethingThatMightReturnNil.if_not_nil { | v | v.doSomethingWithNoHassle }

Which is so much nicer [UPDATE: and nicer still after Sean prompted me to actually get Mark’s example right].

That really does look like Smalltalk, doesn’t it?

Written by hutch

November 22, 2007 at 11:58 pm

Posted in Ruby

One of the Web’s Little Mysteries

Why do people think content management is not possible for static websites?

And another related mystery:

Why do people think dynamic site generation is superior to a static website even when the site does not allow for any kind of reader contribution?

And, I suppose if you know me, there’s a third mystery:

So… why on earth do you care Hutchison? Eh?

Well, maybe I’ll start with the last mystery. I do happen to care. For a couple of reasons.

First, it turns out that I’m biased. I’ve been working on a program called Raconteur for the last few years. Until recently I’ve been in denial, unable to admit that it is, in fact, a content management system — well, I’d admit it was like a CMS but would deny it was a CMS. This lead to painful and prematurely technical discussions of what it does, usually by explaining what it doesn’t do. Ever try to describe something by describing what it isn’t? Sigh.

So last week I think, I tried out the phrase “CMS for static websites”. Good grief! Saying that totally eliminated the need for any of that painful and frustrating conversation. What it did do was introduce a couple of questions, but they don’t come up until much later and when do they aren’t asked very hard (so to speak) — the person I’m talking to already knows the answer they just can’t quite believe it.

You know, sometimes I’m appalled how I miss the obvious. The only defence I’ll offer is that there are well over 100 people using Raconteur and not one of them saw this either.

Those questions that get asked later, after a little reflection and googling, lead to the first two mysteries.

The second reason I care about this is because of the unintended disservice done to the clients of those web professionals who hold the views with mysterious origin. I understand holding those views since they contributed to my denial that Raconteur is a CMS. But they are wrong!

A Fact: Raconteur provides a very comprehensive capability for building and maintaining a large static website that anyone would acknowledge is just like a CMS.

A Fact: Raconteur is not the only software that does this, though the club is very very small compared to the total number of CMSs out there. There are thousands upon thousands of commercial and open source CMSs, and some huge but unknown number of ‘home-built’ CMSs. I know of less than six that do what Raconteur does — I expect that there must be more, but I can’t find them, probably because they are overwhelmed by the other CMSs. [UPDATE: I had intended to link to one of our most interesting competitors: Big Medium]

A Fact: contrary to popular belief, static websites don’t get unmanageable at 20-50 pages. Raconteur’s very first live site was around 4000 pages, every last one of them static. Updates to the website can be made in minutes (if you are daring or foolish, you can do it in well less than a minute).

A Fact: static websites are the easiest, cheapest, and fastest way to deploy a website. How often do you get those three things at the same time?

A Fact: — well, this is really an opinion but I’m saying it’s a fact — most ‘dynamic’ websites out there would benefit by being static, and the rest may well benefit by separating the read-write part from the read-only part.

A Recommendation: think very hard about what ‘dynamic’ and ‘static’ mean, be especially alert to logical conclusions being drawn by inadvertently using synonyms of those two words (this is where I think the second mystery originates).

I’ll go into a few more aspects of this later.

This is going to sound like an advertisement, well maybe it is kind of: Raconteur is in production, though currently most people come to it by word-of-mouth, and every one of them knows that they are ‘early adopters’ and what that means. It isn’t really in ‘stealth’ mode, more like a silent presence. The documentation is, at best, sparse. Even so there are more than 100 websites using it. If you want to know more we’d be more than happy to talk to you. We expect to have the documentation completed sometime in August, at which point we’ll be opening Raconteur to a wider audience.

Written by hutch

August 3, 2007 at 11:37 am

Posted in Raconteur™, Ruby, webapps

Making Raconteur go Vroom

So I was reading this article Making Rails go Vroom by Charlie Savage and thought maybe I’d profile a few of the more frequent actions in Raconteur, which is written in Rails.

The instructions provided in other posts by Carlie are perfectly clear and easy to follow but, inevitably, they don’t work for versions of Rails that don’t implement the alias_method_chain method.

This is the definition of that method:

class Module
  def alias_method_chain(target, feature)
    aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
    yield(aliased_target, punctuation) if block_given?

    with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#

    alias_method without_method, target
    alias_method target, with_method

    case
       when public_method_defined?(without_method)
         public target
       when protected_method_defined?(without_method)
         protected target
       when private_method_defined?(without_method)
         private target
     end
  end
end

You can stick it anywhere that gets loaded early enough by Rails. I put it into the profiling.rb file that comes with the ruby_perf Rails plugin.

It turns out that there was a call to a method that was not strictly necessary, but it had the possibility of touching the database. So I removed that call, and got a fairly significant speed up. Which I thought was interesting. So I poked about some more and discovered that the culprit was the XML escape routine (the one that replaces “<" with "<" and so on). This was really quite bad. I managed in this specific case to avoid the problem, but sometimes it must be run. I think I'm going to have to find a faster implementation of that, maybe even written in C.

Written by hutch

August 3, 2007 at 7:43 am

Posted in Ruby

Want Haml? Stuck using an old version of activesupport?

Then this is what you need to do (if you haven’t already figured this out).

I am using Rails 1.0.0 for an application at my company, and for annoying reasons, I can’t at the moment switch to Rails 1.2.3. This requires activesupport 1.2.5 to be installed. Since there are a lot of things using activesupport other than Rails I’ve also got version 1.4.0 installed.

If you install the haml gem and try to do something like this in a ruby script:

require 'haml'

engine = Haml::Engine.new("%p hello world!")
puts engine.render

you’ll get some ugly looking exception complaining about activesupport 1.4.0 and 1.2.5.

Worse, just by having installed the haml gem other things will break. For example, Merb won’t start because of that same exception.

Luckily, this bit of code works:

begin
  require 'haml'
rescue
  require 'haml'
end

engine = Haml::Engine.new("%p hello world!")
puts engine.render

and merb will start again if you replace the require 'haml/engine' in the lib/merb/template/haml.rb in the merb gem with:

begin
  require 'haml/engine'
rescue
  require 'haml/engine'
end

Written by hutch

June 18, 2007 at 9:51 am

Posted in Ruby, webapps

Unbelievable mess on my tumblelog

From the very beginning, the atom feed of my tumblelog has been using ‘debug’ URLs for links. The associated website was just fine.

So what does this mean? Just that URLs like ‘http://localhost:4000/…&#8217; would show up in the feed. Works on my machine! Unfortunately, works only on my machine.

On top of that, I was dropping the source information for each item in the publication process. That was because I was blind to the problem. I fixed that a couple of days ago.

Sigh.

I hope it is correct now.

Written by hutch

April 8, 2007 at 11:16 am

Using Erubis 2.2.0 with Rails 1.0

I used Merb to build a tool to let me write my new tumblelog ‘So.’. I would likely have used Rails but because Raconteur is still using Rails 1.0, and Rails 1.2 doesn’t seem to want to co-exist with Rails 1.0 on the same machine, I was prevented from doing that. In truth, I wanted to check out Merb anyway, so I took the excuse.

Merb is quite a nice framework, easy to use, and very quick. One of the reasons it is so quick is that it uses Erubis rather than erb. So I thought I’d see if I could get Merb to work with Raconteur.

It didn’t work out of the box. There is of code in rails_helper.rb (which needs to be required in your config/environment.rb file) that:

  • extends ActionView::Base
  • decides that the version of Rails it is working with is before Rails 1.2
  • tries to call the template_requires_setup? method that it thinks is defined in ActionView::Base

The problem is that there is no template_requires_setup? in Rails 1.0

Almost a year ago I wrote a blog entry — Nice Ruby Idiom — that describes a technique that allows you to monkey-patch a missing method into a class while not screwing up the real definition that will appear in some future version. This is precisely the situation I’ve got here.

So…

      instance_method(:template_requires_setup?) rescue def template_requires_setup?(extension)
                                                          false
                                                        end
    

(inserted around line 98 of the file …/erubis-2.2.0/lib/erubis/helpers/rails_helper.rb) does the trick.

It is a bit of a coin toss whether a true or false should be returned… I think I guessed correctly, because it works just fine.

If you are stuck at Rails 1.0 like I am, this might be handy.

Written by hutch

March 24, 2007 at 10:16 am

Posted in Raconteur™, Ruby, webapps