Rails deployment has been solved

Everyone knows that Rails deployment is a massive pain, right? Wrong. It’s time we all erased this outdated notion from our heads.

I just installed Redmine on my server, and it was simple. Thanks to mod_rails, the sum total of web server configuration needed was this:


<VirtualHost *:80>
  ServerName  dev.redcaride.com
  DocumentRoot /home/dbl/redmine/public

  <Directory "/home/dbl/redmine/public">
     Options FollowSymLinks
     AllowOverride None
     Order allow,deny
     Allow from all
  </Directory>
</VirtualHost>

No mongrels, no proxy_balancers, no FCGI (shudder). This was actually easier than when I installed WordPress on the same server last week.

So never again be put off a Rails application because you’re scared of deploying it! The world of open-source Rails applications opens up before you….

Regex Replacer

Here is a little Ruby library that may be useful to you. It is a regular expression string replacing tool. It’s similar to what you can do with String#gsub in Ruby, but with a few more features.

I needed this library to get Textmate snippets working in Redcar, and therefore it uses a slightly different syntax to gsub (”$1″ instead of “\1″). Here are some examples:


rr = RegexReplace.new(/nuclear (\w+)/,
                      "solar $1")
rr.rep("nuclear nutcracker")
=> "solar nutcracker"

So far so obvious. That’s identical to Ruby gsub but with “\1″ changed to “$1″. Here’s something more useful:


rr = RegexReplace.new(/nuclear (\w+)/,
                      "solar \\u$1")
rr.rep("nuclear nutcracker")
=> "solar Nutcracker"

Whee! Letters following “\u” are upcased. What else can it do?

Upcase stretches with \U…\E


rr = RegexReplace.new(/nuclear (\w+)/,
                      "solar \\U$1\\E")
rr.rep("nuclear nutcracker")
=> "solar NUTCRACKER"

You can downcase in exactly the same way with “\l” and “\L..\E”.

Conditional replacement with (?1:then:else)


rr = RegexReplace.new(/nuclear( \w+)?/,
                      "solar(?1:$1: thingy)")
rr.rep("nuclear nutcracker")
=> "solar nutcracker"
rr.rep("nuclear")
=> "solar thingy"

You can also combine the operators in this fashion “\l\U…\E” to get (for instance) “fOO” from “foo”.

If you find it useful please let me know.

Ruby WebKit 2

The Ruby-WebKitGtk bindings are usable. Clone them:

git clone git://github.com/danlucraft/rbwebkitgtk.git

or download them. I’m using the WebKit nightly r31823, YMMV. Build instructions for WebKitGtk are here.

rbwebkitgtk.png

To do:

Ruby WebKit

Update: These bindings are now pretty usable. See here.

This morning I started working on some Ruby bindings for WebKit on GTK. I’ve only been working on them for an hour or so but they can already do this:


require 'src/lib/webkit'

win = Gtk::Window.new
wv = Gtk::WebKit::WebView.new
win.add(wv)
win.show_all
wv.open(’http://www.google.com’)
Gtk.main

to get this:

screenshot-testrb-1.png

The Ruby-Gnome2 team have done a fantastic job of making it easy to write Ruby to GTK bindings. I hope to make good progress on these tomorrow.

Github

Github has some serious awesome. I moved Redcar over there yesterday, and in a pleasant suprise, someone called Russ is already ‘watching‘ it.

And Russ himself is working on a cool idea called gitnub-gtk, which is a port of gitnub to Ruby-Gnome. I know this is a cool idea because I had it myself when I first saw gitnub :-).

So thankyou Github, for introducing me to a project that I would never have discovered otherwise, and for helping make my project more widely known. If I had to say one thing: why is there no way to send messages to each other through Github? Seems like an obvious feature.

github.png

Shell history

Since everyone seems to be doing it:

$ history|awk '{a[$2]++ } END{for(i in a){print a[i] ” ” i}}’|sort -rn|head
189 ./bin/redcar
51 cd
41 gst
29 git
28 irb
23 less
21 ruby
20 gca
19 ls
13 sudo

I guess it’s pretty obvious what I’m spending my time on :).

New version of Rak

I released a new version of Rak today with some bug fixes and enhancements.

New features:

Thanks to Edvard Majakari, Kevin Ballard, Esad Hajdarevic, Bela Babik, Genki Takiuchi and Rob Knight for suggestions and fixes.

rakwin.png

Using Meta-Programming for Performance in Ruby

Normally we use meta-programming in Ruby for our own convenience as developers, and we swallow the speed hit it gives us as a reasonable trade-off. The way Rak is implemented turns this on its head.

Rak compiles its line matching code on the fly, to speed up searching. Its not as horrendous as it sounds. Here’s a very simplified version of the line matching code without the optimization:


def line_match(filename, regex, line)
  if options[:invert_match]
    unless line =~ regex
      if options[:print_filename]
        puts filename
      end
      puts line
    end
  else
    if line =~ regex
      if options[:print_filename]
        puts filename
      end
      puts line
    end
  end
end

We notice that the options hash never changes once the searching has begun. But we are doing an awful lot of work checking the values in the hash for every single line we are matching against. So we replace it with this:


def compile_line_match(filename, regex, line)
  code = []

  code << %{def line_match(filename, regex, line) }
              if options[:invert_match]
  code << %{    unless line =~ regex              }
                  if options[:print_filename]
  code << %{        puts filename                 }
                  end
  code << %{      puts line                        }
  code << %{    end                               }
              else
  code << %{    if line =~ regex                   }
                  if options[:print_filename]
  code << %{        puts filename                 }
                  end
  code << %{      puts line                       }
  code << %{    end                          }
              end
  code << %{end                              }
  module_eval code.join("\\n")
end

I’ve preserved the indenting so you can see the logic of the method. Here all the option tests have been factored out and will only be done once, at startup. Assuming we are not inverting the match and are printing filenames, the final compiled method looks like this:


def line_match(filename, regex, line)
  if line =~ regex
    puts filename
    puts line
  end
end

Much smaller. This method is 140 lines long in the full version, so its a much more impressive win there. All told this sped up Rak by about two times when I tested it searching on my Phd repository (3500 files).

There’s more work to do optimizing Rak. It’s still not as fast as Ack, so you might want to use that unless you are a Ruby fanboy like me :). But I have some more ideas….

Update 20/04/08: thankyou to redditer tomel for pointing out a WTF in the above code :).

Really, really slow graphics in Gutsy?

Me too. I was using an ATI card, without any 3d accel. It worked fine on Feisty, but when I upgraded to Gutsy I found I could watch the windows redrawing.

It turns out* that I had xserver-xgl installed from a previous (failed) attempt to get 3d acceleration working in Ubuntu. Feisty didn’t care, but Gutsy loads XGL automatically if it is installed. And XGL with no acceleration is really really slow.

* Anyone who has used linux/ubuntu knows what getting to ‘it turns out’ entails.

Rak, a grep replacement in pure-Ruby

Rak is a tool for searching directories for files matching a regexp, like a more convenient grep. It gives you pretty highlighted output, and uses the Ruby regexp syntax. To install type gem install rak.

Rak is implemented in pure Ruby, so it should work on all platforms. Windows folk will probably find they need to use the –nocolour option (I will fix this next time I boot into Windows for any reason).

NB. Rak is an almost perfect clone of the Perl tool Ack by Andy Lester. He should get all the credit for the idea.

Next Page →

  • About

    Daniel Lucraft, London, UK. Interested in Ruby, Prolog and software.