# The One Thing I Like About PHP
- <?
- class B {
- function hello() {
- echo "HAI\n";
- }
- }
- $a = "hello";
- B::$a();
- ?>
- <?
- class B {
- function hello() {
- echo "HAI\n";
- }
- }
- $a = "hello";
- B::$a();
- ?>
Gosu is a 2D game development library for the Ruby and C++ programming languages, available for Mac OS X, Windows and Linux.
- require 'rubygems'
- require 'gosu'
- class MyWindow < Gosu::Window
- def initialize
- super(640, 480, false, 20)
- self.caption = 'Hello World!'
- end
- end
- w = MyWindow.new
- w.show
I can’t wait to find the patience to do something cool with this.
I generally use TextMate for text editing these days, so I’ve slowly being building up a bunch of custom modifications to the stock install. The most obvious of these modifications is changing the colours of the syntax highlighting, which matches the code snippets you see on this blog.
If you use TextMate yourself, you’ll know that it supports highlighting multi-line comments differently from single-line comments, but if you’re a Ruby coder, you’ll know that the only kind of multi-line comments it supports is the nasty =begin/=end thing which can’t have any whitespace preceding them and thus messes up your nicely indented code :
- module Supermodel
- =begin
- This class encapsulates all information about a given index.
- Blah blah blah.
- Blah.
- =end
- class Index
- def initialize()
- # Do stuff
- do_stuff
- end
- end
- end
Ugly.
What I ideally want is some way of using the same multi-line highlighting (with the dark grey background) but without having to use =begin and =end, and without having to bind everything to the beginning of a line.
And that’s now what I have, this is a screen grab from TextMate (I’ve not got round to mirroring the changes on the blog yet) :

You’ll notice I’m using ## to mark a line which should be highlighted in that manner, separately from a normal comment beginning with #.
And here’s how I did it!
TextMate’s syntax highlighting turns out to be pretty fantastic and flexible. You can read about it here and here and here, and probably on some other pages on that site too.
The first step is to define a rule for the new highlighting type. From within TextMate, if you go to the Bundles → Bundle Editor → Show Languages menu option, you’ll get a list of languages that TextMate will highlight for. Open the Ruby node in the tree-view, and you’ll see one language – Unsurprisingly, called ‘Ruby’. I copied this, creating a new language called ‘Ruby (double-number-sign highlight)’.
Having read the above about scoping, I changed the scopeName at the top of the new language definition to source.ruby.double-number-sign-highlight to avoid any crazy clashes that might occur otherwise. This might be unnecessary, but it seems correct.
If you then search the language file for comment.line, you’ll get to the place where we need to add our new rule. Here’s the new rule we’re going to add :
- { name = 'comment.line.double-number-sign.ruby';
- match = '(?:^[ \t]+)?(##).*$\n?';
- captures = { 1 = { name = 'punctuation.definition.comment.ruby'; }; };
- },
You can see it’s very similar to the existing comment.line rule. Make sure you add that rule above the existing one, the rules seem to be traversed in order until one matches, and obviously a rule looking for a line beginning with # will match one beginning with ##.
Now that we have the new rule set up, we just need to tell TextMate how to use it. Close the Languages window, and then go to TextMate → Preferences → Fonts & Colors. You’ll see the usual colours you use for your highlighting. To add a new highlighter, click the + button, and a new rule will appear. Set its name to something like ## comment, and set the colours you want to use. Then, importantly, change the Scope Selector entry to read comment.line.double-number-sign (Note that although the field in a drop-down menu, you can type new entries into it too.)
And that’s it! If you open up some existing Ruby code, or create a new file, and ensure that you use the Ruby (double-number-sign highlighting) language (You can set that using one of the menus at the bottom of the TextMate window), any comments you create with ## will be highlighted differently to #.
If you don’t want to go through all the hassle of setting this up yourself, you can download a disk image containing the new language and a theme that highlights the double-hash-sign below :
To install them, just double-click on the files once you’ve mounted the .dmg. They’ll be copied by TextMate to ~/Library/Application Support/TextMate, from where you can delete them if you want.
If you’ve ever been frustrated by the lack of control that most mail clients give you over your signatures, then Siggy Stardust is for you. It’s basically an SMTP proxy, which simply adds signatures to the end of any mails you send according to rules that you set up. The rules are written in pure Ruby, and so you can do pretty much anything you want within them.
For example, here is my current rules file at Teh Office. If all the recipients of a mail are within 29degrees, then a personal signature is appended. If any of the recipients are external to the company, then the business signature gets added. My personal signature tries to include the song I’m listening to at the moment, either on my own computer, or on the company jukebox. It does this by querying either iTunes or last.fm.
- require 'rubygems'
- require 'rbosa'
- require 'scrobbler'
- rules do
- smtp_server( "localhost" )
- smtp_port( 10025 )
- track = nil
- track_string = nil
- begin
- # Try and get currently playing information from either iTunes or last.fm.
- itunes = OSA.app( "iTunes" )
- if itunes.player_state == OSA::ITunes::EPLS::PLAYING
- track = itunes.current_track
- else
- user = Scrobbler::User.new( "29degrees" )
- track = user.recent_tracks.first
- end
- rescue
- puts [ $!.class, $!.to_s, $!.backtrace ]
- end
- if track
- track_string = "\"%s\" by %s off \"%s\"" % [ track.name, track.artist, track.album ]
- personal_sig = <<-EOT
- --
- Now listening to : #{track_string}
- Siggy Stardust r78
- EOT
- else
- personal_sig = <<-EOT
- --
- ASCII a silly question, get a silly ANSI.
- Siggy Stardust r78
- EOT
- end
- business_sig = <<-EOT
- --
- Regards,
- Carl Drinkwater,
- Director.
- http://29degrees.co.uk - Bespoke Web Application Development
- +44 (0) 161 953 6669 - +44 (0) 776 043 1463
- 29degrees Ltd is registered in England and Wales under company
- number 05952987. VAT Reg Number GB897293655. Registered office
- St. George's House, 215/219 Chester Road, Manchester, M15 4JE.
- EOT
- if recipients.all_in_domain?( "29degrees.co.uk" )
- append_sig( personal_sig )
- else
- append_sig( business_sig )
- end
- end
(Does anyone else think heredocs are ugly?)
Siggy tries to be intelligent when adding signatures to multipart emails. For me, the best results have come by adding the signature to the end of the last text/plain part of the email, and so that’s what Siggy does. It doesn’t attempt to do anything with text/html emails, because it shouldn’t need to.
If you want to play, download Siggy Stardust here. Run it by doing something like :
- ruby ./server.rb rules.rb
You’ll need to re-configure your mail client’s SMTP setting to use localhost and port 1234. By default, Siggy will proxy through to port 25 on the local machine, but you can change that by using the smtp_server and smtp_port methods as in my rules file.
The only other real helper functions are demonstrated in the final lines of my rules file :
- if recipients.all_in_domain?( "29degrees.co.uk" )
- append_sig( personal_sig )
- else
- append_sig( business_sig )
- end
You will probably need to write more to do the things you want, you’ll need to do that in server.rb.
To use the ‘now playing’ functionality, you’ll need the appropriate Rubygems installed. The iTunes lookup uses RubyOSA, and is only available on OS X.
Lastly, the rules file is reloaded each time you send an email through Siggy, so you don’t need to restart the server if you edit your rules.
The two files comprising Siggy Stardust, rules.rb and server.rb, are placed in the public domain. However, note that the gzipped-tar archive you can download above comes packaged with TMail, and is licensed under the LGPL.
A bit of Friday fun. Golfr saves you all the hassle of having to type out full method names by letting you use as few characters as you need. Look at the examples to see how it can save you valuable keystrokes.
- module Golfr
- def method_missing( method, *args)
- endings = Regexp.new( /[!?=]?$/ )
- ending = method.to_s =~ endings ? $& : ""
- ( look_for = method.to_s )[ endings ] = ""
- if found_method = ( methods.sort.select{ |m| m =~ /^#{look_for}/ }.first ||
- methods.sort.select{ |m| m =~ /#{look_for}$/ }.last )
- found_method[ endings ] = ""
- STDERR.puts "Calling #{found_method}#{ending} for #{method}" if $DEBUG
- send ( found_method + ending ).to_sym, *args
- else
- raise NoMethodError, "#{method}"
- end
- end
- end
- class Object
- include Golfr
- end
Then have fun!
- require 'golfr'
- a = []
- $><"Hello\n" # Matches '<<'
- a.uns "Cheese" # Matches 'unshift'
- a.ft [ "Pickle" ] # Matches 'unshift'
- puts a.insp # Matches 'inspect'
- a.fl! # Matches 'flatten!'
- puts a.pect # Matches 'inspect'
- puts a.n? # Matches 'nil?'
- puts "carl".c # Matches 'capitalize'
- Thread.a = true # Matches 'abort_on_exception='
Set $DEBUG=1 if you want to see what methods are actually being called, and feel free to do what you want with the code. It’s all yours.
This week, I was moving my iTunes library off an external HDD to a network share and somehow managed to completely badger it up. All the songs were still showing in iTunes and they were all on disk in their original places, but something had happened to their location in the iTunes database and were showing with an exclamation, indicating iTunes couldn’t find them.
After fixing these by trying to play the songs and manually locating them on disk, I was still finding songs which weren’t indicated by iTunes as missing, but actually were. So, I quickly wrote the below script to list all the broken tracks in my library. Unfortunately, there doesn’t seem a way to set the location automatically.
So yeah, I don’t know if this will be useful to anyone else, but here is the code …
- require "rubygems"
- require "rbosa"
- library_playlist = OSA.app( "iTunes" ).sources.find{ |s| s.name == "Library" }.library_playlists.first
- # Songs which are broken have a location of 'nil', but still have the
- # rest of the information.
- library_playlist.file_tracks.reject{ |t| t.location }.each do |track|
- puts '"%s" by %s, off "%s"' % [ track.name, track.artist, track.album ]
- end
The (old) “standard” way of extracting an optional options hash passed as the last parameter of a method call :
- def add_food( *args )
- options = args.last.is_a?( Hash ) ? args.pop : {}
- puts args.inspect
- puts options.inspect
- end
- add_food( "cheese", :edible => true, :drinkable => false )
- => "cheese"
- => {:edible=>true, :drinkable=>false }
This is something I’m seemingly doing more and more, and let’s face it – It’s ugly.
However, as of changeset 7217 (and the original ticket) of Rails, a method has been added to Array encapulate this. You can now do :
- require 'active_support'
- def add_food( *args )
- options = args.extract_options!
- puts args.inspect
- puts options.inspect
- end
- add_food( "cheese", :edible => true, :drinkable => false )
- => "cheese"
- => {:edible=>true, :drinkable=>false}
Such a simple addition, it’s hard to believe there wasn’t already a method to do this.
Update: And yes, I realise my examples above are crap – Hopefully you can see what’s happening though.
- #!perl -l12e
- $_=1;($_,$?)=($?,$_+$?),print while$_<4e3
41 bytes, excluding the shebang line. Written for this.
- a = [ 1, 2, 3, 5, 6, 2, 3, 1, 4, 5, 4 ]
- puts a.inject( 0 ) { |c, i| c ^= i }
Find the unpaired number in an array. I can’t really think of a situation you’d need to do this, but it’s a really, really elegant solution and that’s why I’m posting it. It’s left to the reader to work out how it works. From.
<code> defines computer code text
From.
[the] lang [attribute] ... sets the language code
From.
the latest rfc describing language tag syntax is rfc 4646 …
From.
language tags are used to help identify languages … for the purpose of communication. this includes constructed and artificial languages, but excludes languages not intended primarily for human communication, such as programming languages
From, section 2.
That’s useful then. Is there actually a way of indicating the programming language used in a code element?
- table :user, options => "TYPE=InnoDB" do |t|
- # Adds has_many :tasks to the model, and adds an index on the target column
- # in the associated table (tasks.user_id, in this case.)
- t.has_many :tasks
- # Create a VARCHAR(50) NOT NULL column, validates_length_of :login,
- # :in => 5..50, validates_presence_of :login, validates_uniqueness_of
- # :login and a unique index for the column.
- t.string :login, :limit => 5..50, :null => false, :unique => true
- # Create a VARCHAR(40) NOT NULL column ready for a SHA1 hash of the
- # :password field. Also adds validates_confirmation_of :password, and an
- # accessor for :password_confirmation. (:confirmation isn't limited to
- # passwords, although it's the main use of it.)
- t.hash :password, :limit => 4..16, :null => false, :confirmation => true
- # Create a DATETIME NOT NULL column for created_at
- t.created_at
- end
- table :task, :options => "TYPE=InnoDB" do |t|
- # Adds belongs_to :user, :allow_nil => true to the model. Also adds an
- # user_id INTEGER column, and creates an index for it.
- t.belongs_to :user, :allow_nil => true
- # Adds a VARCHAR(128) NOT NULL column, validates_length_of :title, :in
- # => 1..128, validates_presence_of :title, and an index for the column.
- t.string :title, :limit => 1..128, :null => false, :index => true
- # Adds a DATETIME column, no validation.
- t.datetime :due
- # Adds a BOOLEAN NOT NULL DEFAULT FALSE column. Doesn't add a
- # validates_presence_of validation.
- t.boolean :done, :default => false, :null => false
- # Create DATETIME NOT NULL columns for created_at and updated_at
- t.timestamps
- # Create a unique index for the two columns due and done.
- t.index :due, :done, :unique => true
- # Create an index for the two columns user_id and title.
- t.index :user_id, :title
- end
So, you’re a Rails developer? CHECK! You have this great idea for a new application, the one which will surely get Yahoo and Google involved in a bidding war? CHECK! But you don’t actually start developing it because you are fed up having to run script/generate model model_name, editing the migration for the table, writing the tests for all the rules which are implied by the database (Such as maximum lengths for columns and column uniqueness), and then editing the model to pass those tests? CHECK!
To solve this problem, you can see the proposed syntax for my (tentatively titled) dont_fucking_repeat_yourself plugin. After creating a file much in the manner of that above, you simply run the (tentatively titled) i_am_bored_of_repeating_myself rake task and all your models, migrations and tests are generated.
It will also allow you to add new models during development, so no longer will you think “No, I won’t add that feature because it requires a new table and I can’t be arsed doing the create-model-write-migration-write-tests-edit-model dance.”
Obviously this only helps with the initial creation of models and doesn’t attempt to help you when you want to change your title column to hold more than 128 characters, but man, it should really speed up those early days of development.
If anyone has any comments let me know, a link to my email is at the bottom of this page. Hell, if anyone reads this at all, it’ll be good to hear from you.
(And if anyone is offended by the swearing, I’m sorry, but DHH started it.)
- 40.times{puts((0..7).map{rand(?{).chr=~/[^\W_]/?$&:redo}*"")}
All in 61 bytes. Can you make it any shorter?
Say you have some pages which are publicly accessible, but have some admin-only links on them when someone is logged into the site. Also, let’s pretend that you’re going to be Slashdotted any day now, and you want to cache the pages, and you quite fancy using Rails’ page caching because it’s nice and easy to use.
“But”, I hear you cry, “if you use caches_page in your controller, it’ll cache the page regardless! You’ll cache your admin links! Everyone will be able to see that you have ajaxy editing on your blog!”
NO! NOT ANY MORE! As of this afternoon, that’s not the case! Read on!
Stick this in lib/dead_good_caching.rb :
- module ActionController
- module Caching
- module Pages
- module ClassMethods
- alias_method :rubbish_caches_page, :caches_page
- def caches_page( *actions )
- return unless perform_caching
- if_proc = actions.last.is_a?( Hash ) ? actions.pop[ :if ] : nil
- actions.each do |action|
- class_eval "after_filter { |c| c.cache_page if c.action_name == '#{action}' and ( not if_proc or ( if_proc and if_proc.call( c ) ) ) }"
- end
- end
- end
- end
- end
- end
Then, in your config/environment.rb file, somewhere near the bottom :
- require 'dead_good_caching'
Then, in your controllers, you can do something like :
- caches_page :list, :tag, :show, :if => Proc.new { |controller|
- not controller.logged_in?
- }
The above won’t cache your last, tag and show actions if you’re logged in! Good eh? If don’t want to do any checking, you can still use caches_page as God^WDHH intended.
“But”, I hear you cry louder, “if a non-logged in user visits the page, Rails will write it out to disk, and because you’ve configured Apache to not bother Rails if a file exists on disk, you, as an admin, will get served that cached page!”
Ah ha! I have to admit, it took a few minutes to figure out a workaround for this. But, assuming you have the ability to mod_rewrite on your server and that the cookie’s name which is set when you login is your_cool_cookie_name, you just need to add something like :
- RewriteRule ^/$ /index [QSA]
- RewriteCond %{HTTP_COOKIE} !(your_cool_cookie_name=(.*?))
- RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.html -f
- RewriteRule ^(.*)$ $1.html [QSA,L]
to your vhost or .htaccess and you’ll be set. Unless I’ve messed up the rules, which I may have done.
As (almost) always, the above code is public domain.
(Update : My procrastination has led to someone else submitting a patch for Rails Core and getting it accepted. See here and here. The upshot is that in Rails 2.1, you won’t need the above hack.)

Here is a quick and dirty script to display images in your terminal (Which is something I want to do fairly often.) It works best in a terminal which supports 256 colours, but gives sort-of-OK results in 16-colour terminals. And despite what the name might imply, it works with pretty much any image type, not just jpegs.
In case anyone else finds it useful, here it is. You’ll want RMagick installed, and both of these files :
Simply run it giving an image as an argument to the script :
- ruby xtermpeg.rb FuryCow_120.jpg
(And here is FuryCow_120.jpg, should you want it.)
Or, if you want to display a large image :
- convert FuryCow_1200.jpg -scale 100x /dev/stdout | ruby xtermpeg.rb
(And here is FuryCow_1200.jpg, should you want it.)
The code is public domain, so you’re free to do whatever with it.

Have you seen Lastgraph or Lee Byron’s work? Like it? Upset you can’t see the source code and play with it? Well, this might be what you’re after.
Utilising the scrobbler gem, I’ve written some Ruby which does something similar, and here’s the code so you can play with it yourself.
Just change the username on line 100, and run it. The script will download your data from last.fm, and produce a nice .svg for you (Warning: quite large.) To be friendly to last.fm, it caches the data on disk, so subsequent runs are generated a little quicker than your first run.
If you want to hack around with it, then I warn you that the second half of the source code is nasty, but subsequent versions will be tidier. It should be fairly easy to work out and modify. The code is released into the public domain, do as you please with it.
I’m sure some of the calculations in the code are inadvertently tailored to accounts with a similar amount of data as mine, so I’d be interested to hear if anyone does have any success with it. Email me via the link at the bottom of the page.
Posted in Code, DataVisualisation, Music, Ruby • 22.06.07 • #
As promised, the C implementation of the Univeral Machine for the ICFP 2006 contest. It’s considerably quicker than the Ruby version, especially if compiled with optimisations :
- $ gcc -c -O5 um.c
- $ gcc -o um um.c
I’m getting into the actual challenges now, I have 360 points so far, which would put me in equal 277th place on the scoreboard. There’s a long way to go …
In preparation for ICFP 2007 that I’ll probably not end up actually doing, I’m having a go at the 2006 contest.
Here is my Ruby implementation of the Universal Machine. It’s very slow, but it works. C version to follow.
- $ cat test.php
- <?
- if( !isset($_GET['filename']) || strpos($_GET['filename'],"../") ) {
- die();
- }
- echo "Hacked.";
- ?>
- $ wget -q -O/dev/stdout http://localhost/test.php?filename=../../../../etc/hosts
- Hacked.
Get them to explain why you’re hacked. If they don’t know, don’t give them the job.