Getting your sql queries in merb

Annoyingly enough, i looked for this for the better part of 20 minutes, so i'm just going to make a note of it here, so that the next time i forget it i can safely feel like a huge tit when the search leads me to my own vegetable-rich blog.

Merb::BootLoader.after_app_loads do
  # Add dependencies here that must load after the application loads:
  # dependency "magic_admin" # this gem uses the app's model classes
  DataObjects::Sqlite3.logger = DataObjects::Logger.new(STDOUT, 0)
end

The class obviously changes if you're using a different database

P.S.: Future-me, if you're reading this, you're an enormous twat. That is all

Tribby codings in the Berlins

So yeah, i'm in Berlin, waiting for the Bratwurst and i just remembered that it's really cool to say stuff like "I went to <x city> and hacked on <y project>".

I was going to say something clever but the gist of it is that i found this code, it does stuff, and it makes tribby look like a thing with bars. And as everybody knows, bars are aweseome.

Justin Palmer's commits to gitnub, in lovely bars !

Tribby: Github embeddable contribution graph

Hopefully i don't steal any names with this one :P.

As the title aptly puts it, Tribby is a tiny flash app that displays a user's contribution to a repo, much like the nice bar thingies do on github. The nice thing about it, though, is that it makes it dirt easy to just roll your own contribution visualisation dingies, since all the cheesy data transfer-conversion part is done for you, so you're just left with an array containing the number of commits belonging to the user and the total number of commits.

My ugly first attempt at getting something showing looks like this:

That shows Sam Smoot's contribution to the datamapper core repo. Much love to mr. Smoot !

It's fully scalable, so if you want it bigger or smaller, just change the width and height and you're all set. The danger is that if you make it too small you won't be able to make out crap, and if you make it too big it'll just make people cry and call you a meanie. Whichever works best for you.

The level of actionscript you need to know to start making your own visualization isn't really that high so you could start experimenting armed only with the AS3 LiveDocs and the awesome Sprouts gem. Big tanks to Luke Bayes for a fantastic job on that project.

Anyway, that's about all there is to say for now, feel free to check out the readme in the Tribby repo, fork it, kill it, make it bake cookies and such. Any questions or whatnot, hit me up on twitter or just leave a comment.

Inflector fun with datamapper and merb

Uh, really awkward. I've been posting so little that i've actually forgotten what the standard post structure is like, and am now forced to steal despicably from my other posts. I'm a dirty thieving bastard :(

But, i digress.

As of late, I've been messing around with merb for a personal project of mine, as old men do in the privacy of their own homes. Being the original fellow that we all know i am, my project has nothing to do with lolcats. Wanting to enforce that as thoroughly as possible, i decided to send a clear message to everybody, and screw up the inflector for 'lolcat'.

Long version ( filled with passion and romance )

It seemed like a good idea at the time, although i must admit, alcohol was involved.

Lawfully, i read the init.rb file, and found the code i was craving:

# Here we define erratum/errata exception case:
#
# Language::English::Inflector.word "erratum", "errata"

"If it works for a fancy word like that, it's sure to work for 'lolcat' !", i thought, conspiring to the demise of humorous felines. Alas, having uncommented that piece of code, i was greeted by my old friend, the shit storm. Do say hello

/Users/zmack/Projects/omgpron/config/init.rb:133: uninitialized constant Language::English::Inflector (NameError)
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/lib/merb-core/bootloader.rb:304:in `load'
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/lib/merb-core/bootloader.rb:304:in `load_initfile'
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/lib/merb-core/bootloader.rb:253:in `run'
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/lib/merb-core/bootloader.rb:65:in `run'
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/lib/merb-core/server.rb:51:in `start'
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/lib/merb-core.rb:87:in `start'
        from /Library/Ruby/Gems/1.8/gems/merb-core-0.9.4/bin/merb:12
        from /usr/bin/merb:19:in `load'
        from /usr/bin/merb:19

Dug around a bit, turns out the class was Language::English::Inflect. No worries, we just change it to that and it does the trick. Well, not really.

>> "locat".pluralize # omg omg ?
=> "locats" # gnoes :(

Elegantly, i break out the hammer, and mightily unleash it upon the unsuspecting merb

require 'ruby2ruby' # => true
"lolcat".method(:plural).to_ruby # => "def plural\n  English::Inflect.plural(self)\nend"

What is this treachery ? I was strictly instructed to use Language::English::Inflect and now this doppelgänger comes to haunt me ?

The trouble is, apparently, that Datamapper's extlib, being the eager little beaver that it is, also implements a pluralize method, and uses the english gem with no namespacing.

Using English::Inflect in init.rb results in more fail, as Datamapper apparently isn't loaded by that time. The thing that came to my mind by this point was to just stick the inflector rule in a model. If it's loading a model, Datamapper is bound to be loaded, wouldn't really make sense to be in the model without Datamapper, so our Inflector is bound to be in reach down there.

And now, after a hard day's work, it is finally time to admire the fruits of our labor

"lolcat".pluralize # => "lolyourmum"

Awesome !

Short version

If you're using merb and want to add a custom inflector, the init.rb comments are bunk, and what you have to use is

Language::English::Inflect.word "erratum", "errata"

Moreover, if you're also using Datamapper, the method on String gets monkeypatched, so you need to patch DM's inflector as well, by sticking the following in one of your models ( well, _near_ them anyway )

English::Inflect.word "erratum", "errata"

class SomeModelOmg

Badjo progressing faster than a nine inch nail through a rotting casket

Been hacking away at this for a couple of days, and this is pretty much where i'm at currently.

  • Gravatars get shown ( yay )
  • Added project details when clicking on a repo ( have to add some sort of transition thingy but right now i can't think of a decent one so right now the text just magically appears )
  • Made the whole thing fully resizable
  • Scrolling for the project list ( the white circles control it - rubbish, i know, but MAGIC ! )

So here's a quick look at what's what, and seeing as Cristi let me know that i apparently stole Nic's son's name, this demo is entirely dedicated to him !

Badjo preview ;o

Stick a username in the input box, hit 'go', and it should either display a sad Octocat ( stuff failed, world coming to an end ), or actually display your repos. Your gravatar won't get displayed quite yet, sorry :( It was a big adjustment for me as well. But until i fix it, you can have Octocat ! Octocat's just as awesome, if not, even more awesome !

Right, so this is pretty much it, if you look at the html in this post, after you overcome your gag reflex at all the rubbish in there, the "FlashVars" section of the flash snippet of the code contains the git user, and the bgcolor param and embed attribute control the movie's background color.

If you click around on stuff nothing happens, for the moment and i'm still bouncing around ideas of what it should actually do on click, so if you've got any suggestions leave a comment, hit me up on twitter, or just fork it and hack it to bits :D.

Badges, anyone ?

For the past month or so i've been doing ActionScript 3. It's typed, it's compiled, and it has this 'dynamic mode' that allows you to basically code it like it's straight javascript, but that incurs some sort of performance penalty, but nobody knows the exact value of that penalty. Long story short, it's ok.

This would pretty much justify the lack of posts since the amount of new information i could share on ruby topics has dropped by quite a bit. But, i digress.

So it's easter and i'm having a beer and snooping around the interwebs looking for pictures of monkeys arm-wrestling, and one thing leads to another and i notice that Github has an api, and aforementioned api works with json as well. Being the go-getter i am, i start pondering about stuff i could possibly do with this new-found gem, and the first thing that pops out is "some sort of thing that displays a person's repos !".

Ten or so minutes later, just as i'm setting up and grabbing another beer, dr. Nic starts showing off the javascript badge thing that he'd done. Epic cryface ensues, but then, with renewed force, i decide to make mine not bigger, not better, but DIFFERENT !.

Nic made his with TDD ? Well screw that, i'll go hardcore, NO TESTS WHATSOEVER.

Nic made his using jquery ? I'll... well, that doesn't really count, since i'm using a different language. BUT it's different nonetheless !.

Also, it has rounded corners. Rounded corners are always a big win.

So anyway, without further ado, here's the repo. It's in pretty much what i'd call 'early alpha' right now, or in layman terms "LOL IT KINDOF WORKS !", but it gets the job done. I'll put a post up with a test so you can check it out for yourselves in a bit. ( no clue about the name tbh, at first i thought it would be cool to have it be like, "badge" + "banjo", because banjos are inherently cool, but now i think it's rubbish, so meh :'[ )

Vim Tip Tuesday

For the past few days i've been basically migrating all of my working hours over to another machine. While this sounds horrendously dull and annoying, i can pretty much assure you that it is. The most annoying thing, by far, though has been getting vim to act the same as it had on my former electronic helper.

The quick fix for this would've been to just import chelu's hardcore .vim folder, but that just left me with a nagging feeling that i wasn't actually using all of the stuff in there. I wanted to go bare bones, raw bit mode, hunter hunted, man and nature, leaf and squirrel ! In layman terms, i just wanted to know what the hell each line of my conf was actually doing, instead of importing 2000 lines of stuff which had a pleasant outcome.

In the end, the stuff that i managed to boil my config down to contained two main things:

Having vim not deselect after indenting in visual mode

This irritated me more than having warm beer served to me by a fat waiter. I'd continue on with the prose on this topic, but the bulk of the matter is that it pissed me off. This fixes it, or rather it uses a 'large hammer' approach to solve this issue

vmap << >gv
vmap >> >gv
It basically tells vim to reselect the last selection after shifting left/right. Not the most elegant approach, but most effective.

Temp files all over the place

You know vim tempfiles. They're those things that show up when you want to check the status in your SCM of choice and just piss you off by being the background noise to your lovely afternoon on the country. The way to swat this nuisance is to simply tell our lovely friend vim to place his goddamn trash someplace else. Anywhere else, but preferably somewhere we would have nothing to do with it. The way to do this is to alter the directory variable in vim. Initially, that lists "." as the first acceptable option. Just set it to something else, or simply erase the "." folder from the bunch, and you're good to go. Gray hairs no more !

Today is not today

Hello there, kind and generous readers. It's been a while since my last post, and i'm quite sure i have been sorely missed. I would really like to say something along the lines of 'the past few months have been really really hectic and i have been immensely busy' but that would be somewhat untrue. The fact of the matter is that i've been doing lots and lots of javascript nothing really seemed that blogworthy i'm a lazy slob.

But from today onwards, i have decided to be a lazy slob no more ! Regular, coherent blogging here i come ! Well, mostly regular, can't quite guarantee coherency on my part. But, i digress. Today's topic is the lovely rubygems and the most disturbing fact that in version 1.0.1,

Today is not today

Just so you know what i'm talking about, in case you have rubygems 1.0.1 installed and ruby 1.8, fire up irb and do the following :

require 'rubygems'
Time.today == Time.today
The thing that'll probably show up will most likely be something along the lines of "=> false". There is a slim chance that it'll return true, but more on that later. Actually, scratch that; more on that now. If you turn that lovely today into a float, you'll be greeted by a lovely bunch of numbers. They may be quite similar to the following:
irb(main):003:0> Time.today.to_f         
=> 1201384800.62603
What may have already gotten your senses tingling should be that floating point part. What's that doing in our upstanding, fixed, and morally responsible time for the present day ? Does our day start at a random millisecond ? Nay, i say ! It does not.

Ok, so we know what the problem is, namely that somebody forgot to trim the floating point part, and we know roughly where it is, namely somewhere inside rubygems. After some grepping, you should find this little gem ( very subtle pun ! ) inside specification.rb:

# Time::today has been deprecated in 0.9.5 and will be removed.
if RUBY_VERSION < '1.9' then
  def Time.today
    t = Time.now
    t - ((t.to_i + t.gmt_offset) % 86400)
  end unless defined? Time.today
end
This is your typical good news - bad news scenario. The good news is that this thing's getting removed, the bad news is that it's buggy, it's in your code, and it's making the very fabric of time collapse upon itself. The way to fix it is quite complex, and instead of giving a rather lengthy and enlightening explanation of its inner workings, i'll just paste the fixed code.
# Time::today has been deprecated in 0.9.5 and will be removed.
if RUBY_VERSION < '1.9' then
  def Time.today
    t = Time.now
    t - ((t.to_f + t.gmt_offset) % 86400)
  end unless defined? Time.today
end
Having read all that reworked and finely retuned code, please take a moment to grab a cup of tea, watch a video, or do whatever you find most relaxing. The last thing i would like to do is strain the honorable reader.

So that's basically it. I've submitted the bug here, and in case you'd like to fix your version before the new one comes out, look for specification.rb in a folder resembling "/usr/lib/ruby/site_ruby/1.8/rubygems". It doesn't have to be identical to that, but that "site_ruby" part is pretty much a given.

A mighty factory worker

In my last post i ranted slightly about having a factory instead of fixtures and why i think it's worth doing. The problem with Dan Marges' Factory is, however that it tends to create a whole lot of junk you don't need.

Allow me to explain. Let's take this snippet

def self.create_newspaper(attributes = {})
  default_attributes = {
    :customer => create_customer,
    :headline => "Read all about it!"
    :paperboy => create_paperboy
  }
  Newspaper.create! default_attributes.merge(attributes)
end
Let's say we had a paperboy already created in this particular situation and we passed it to the method via the attributes param. After this call, like it or not, we'll be stuck with two paperboys. Add to this validations and the fact that the point of factory is to write less test data than you would with fixtures and you'll most likely see my point.

So let's recap what we'd like. We'd like something that creates all attached models to the one we call, and we'd like it to do so without screwing up every single thing in the universe. Sounds easy enough.

Let's say we have pickle which belongs to jar which belongs to shelf. When we call create_shelf we'd like our mighty class to also create pickles and jars to go along with our nice green shelf.

Now at the time i had realised the simplicity of my needs, i had already gone into a great deal of trouble and writing to order my functions in a 'factory' sort of way. I had create_pickle, create_jar and create_shelf all ready, and waiting for my signal. Not wanting to reformat all my code, i namely my newly-created method 'clever_create'. Its story was as follows

  def self.clever_create(klass, existing = {})
    call_stack = [:pickle, :jar, :shelf]

    create_params = {}

    call_stack.each do |current|
      create_params[current] = existing[current] || eval("self.create_#{current}(create_params)")
      break if current == klass
    end

    create_params
  end
That should pretty much take care of creating your objects for you and return your whole bunch of stuff in one neatly packed hash. The only problem is that, since you're doing a merge on the create_params in your create functions, some of those keys might not have methods in your models. As such, you should change your merge to an exclusive merge, which, oh noes, is not present in the manual ! What are we to do ? One option would be to run around screaming in anguish and dismay until we feint, another would be, as we are in ruby, to just create one.
class Hash
  def exclusive_merge(other)
    self.each_key do |key|
      self[key] = other[key] if other.has_key?(key)
    end
  end
end
So there it is. If there is one already, i couldn't find it because it isn't called 'exclusive_merge'. If there isn't, then it's all good.

There would be more to add, but sadly my alcoholic beverage of choice is getting quite warm by now, and i must continue another time. As such, i bid you farewell and good fortune !

On testing - part one of many

Hey there, people. As you may or may not have noticed, i haven't really been writing all that much for the past few weeks, but now i have returned and am fully prepared to deliver upon the afore-promised bacon !


So i've been reading and writing a lot of tests for an existing application, and the grand conclusion i have come to is that fixtures are rubbish. There are a number of tests one can not carry out without using fixtures, but for the greater part using a Factory-based approach is more fun to both read and write.


The reason i like creating objects in my test rather than having fixtures is that it's easier to keep track of the things i have in my database and it makes the models easier to understand for people who are new to the codebase. For you it may be quite obvious that you need to create a Widget before you create a Kludgel and a Porkchop that need to be linked to a Fricasee and a Frisbee with a diameter greater than 15, but having to swim around the codebase to gather that whole structure would take a lot more time and be considerably more boring than just having it laid out in front of you in a test and being able to play around with.


One thing that doesn't really work that well when you're writing tests for an existing codebase is mocking. You generally want to write code with mocking and ease of testing in mind. What that usually leaves you with is a lot of skinny methods just ripe for mocking, stubbing, and isolating the liver out of your unit tests.


Also, another thing to look out for is that posts containing no code at all look surprisingly smaller than posts containing code. As such, I shall return soon bearing gifts of both code and posts !

Even more metaprogramming

Well, it's been a couple of weeks since i've posted anything and i do feel quite guilty about it. Therefore, i shall post more metaprogramming ! In the project i'm currently working on, it has been my great displeasure to encounter blocks similar to the following

def xml_goats
  configuration_node.root.elements["goats"].text.strip
end
  
def xml_apples
  configuration_node.root.elements["apples"].text.strip
end
  
def xml_cherries
  configuration_node.root.elements["cherries"].text.strip
end

I don't know about you, but to me, that just screams "metametametameta !!!". And it's not just because i'll use any excuse to stick some metaprogramming in my classes, but it genuinely looks like a load of nasty copy-paste malarkey. As such, i proceeded with my evil deeds

class Margerine
  %w[goats apples cherries].each{|x| 
    class_eval(%Q{
      def xml_#{x}
        configuration_node.root.elements["#{x}"].text.strip
      end
    })
  }
end

This by all means pretty much works as expected, and defines all those lovely functions for me. However, it still leaves me feeling a bit empty and unsatisfied. What if someday, somehow, we have more of these functions and they require a different set of method calls on the given node ? What will happen to our beautiful code then ? Will it be thrown to the gutter, like an old mistress with a dirty stocking ? Will it be fed to the wolves, like a lovingly furry squirrel who has eaten one too many hazelnuts ? That would most certainly not do. As such, we must make our code better, stronger, and even more delicious.

class Margerine
  def self.attr_xml_reader(items,submethod = "text.strip")
    items.each{|item|
      class_eval( %Q{
        def xml_#{item}
          configuration_node.root.elements["#{item}"].#{submethod}
        end
      }	)
    }
  end

  attr_xml_reader %w[goats apples cherries], "text.strip.downcase"

end

Now we are indeed satisfied with our work, and knowing that all damsels and squirrels the world over are safe and sound, we rest to code another day

Tasting the sweet nectar of metaprogramming

Metaprogramming is something you hear a lot about when you're around ruby, and with good reason. It's insanely powerful and hands down the most fun you can have with a programming language. Given that it's quite a complex topic, i'll start off slow - custom getters and setters. If you've used ruby for more than 20 minutes, you've probably seen attr_reader / attr_writer / attr_accessor. They're snippets of metaprogramming that just generate methods. Take attr_accessor, for instance. It gets you something to the tune of
def #{name}
  @#{name}
end

def #{name}=(value)
  @#{name} = value
end
But let's say you need something slightly more complex than that. Let's say you're writing an application which features sock possession reporting for animals with silly names. At least in my line of work, that's quite a common requirement. Being the magnificent human being you are, you'd like to write as little as possible. Therefore, you define a module
module Sockless
  def no_socks_for( *names )
    names.each { |name|
      class_eval("
        def #{name}_has_no_socks
          @#{name} + ' is a ghastly beast with no socks'
        end

        def #{name}=(value)
          @#{name} = value*2
        end")
    }
  end
end
Now you just have to extend your desired class with the Sockless module and you're home free
class TheSockZoo
  extend Sockless
  no_socks_for :pig, :sheep
end
Subsequently, you can amaze all sentient beings within a 10 mile radius by just adding these three lines of code and viewing the wonders of modern technology in action
r = TheSockZoo.new
r.pig,r.sheep = "gi","dee"
p r.pig_has_no_socks, r.sheep_has_no_socks

Using block helpers to make your views pretty

I was watching the code review that Jamis Buck and Marcel Molina did for the Mountain West Ruby Conference and one really nice idea that grabbed my attention was using block helpers to separate sections in views.

Let's say you have a view and you need to render a partial with some content which only people who love delicious pickles should see.

<% if @user.loves_delicious_pickles? %>
  <%= render :partial => "pickles" %>
<% end %>
That's perfectly fine, but should your pickle logic get more complicated, you'll be stuck with an ugly looking conditional statement in your view.

The alternative would be to add a helper to your controller and move all your logic in there

def lover_of_delicious_pickles
  yield if @user.loves_delicious_pickles?
end
Which would turn your view into something to the tune of
<% lover_of_delicious_pickles do %>
  <%= render :partial => "pickles" %>
<% end %>
Granted, this isn't the best example but the idea itself is really good, and should at least make your code easier to understand.

More on this here.

Syndicating other people's content for your own selfish use

I've grown to love and adore google reader. It's the only tab that stays open for the entire duration of the day in my browser, mainly because if you subscribe to the right feeds, there's always something good to read. The thing is, feeds have made me lazier than i should be, namely, checking sites for stuff i want has suddenly become a chore. It's like calling the post office every day asking Mr. Wabu, the postal server, if any letters have arrived for you, instead of having the kind-hearted Mr. Wabu drop by your house every day and just deliver your loving bills in your lovely mailbox.

As such, i decided this could not go on any longer. Mr. Wabu had to come by my house. Enter the Ruby !

In case i've been too abstruse up to now, what i mean to do is syndicate the content of a website which, while relevant to me, has no rss feed of its own. For this particular example i'm using Hpricot for the ingenious act of spidering, and the omnipotent builder to generate the xml. I'm quire sure there are a number of gems/libraries out there that can generate rss much easier than builder, but this was the first one that came to mind and it is quite delightful to work with.

Ze Spider

I'd used to do spidering using just open-uri and scan, as i found writing 3-row regular expressions for my desired data a delight. This time, however, i wanted to do something wild, so i went with Hpricot. This involves doing something to the tune of

open(address) { |file|
		doc = Hpricot(file)
		doc.search('td.content table table table tr') { |match|
As you can probably figure, the parameter for search is a css-style selector for a horribly built table layout. We want this field's prized possession to become our own, so rob it of its data and see if it is of any use to us
if ( match.innerText =~ /pickles/ )
Yes, we are looking for pickles.
Upon having found said pickles, we store their title, address and description somewhere, so that we can get them when we build the feed. I used a hash
date = match.children[0].innerText.split('/')
				date = Date.new(2000+date[2].to_i,date[1].to_i,date[0].to_i)
				results << { 	:title => "#{title} #{match.children[2].innerText}",
								:link => match.children[5].search("a").attr("href"),
								:body => match.children[5].search("a").attr("href"),
								:date => date
							}
I was looking into a row, and the sixth child contained the link so, not being interested in the link's inner text, i just used Hpricot to extract the link's href.

Ze Feed

Moving on, let's say we have the results we need, so now we have to generate our feed. I used builder to get this done, mainly because it's easy to understand and the syntax is pretty much gorgeous. The feed is rss 0.91 because i was looking for something really simple, which google reader could understand. If you want to generate some other kind of RSS you can find the specs here.

def midgets_to_rss(midgets)
	xml = Builder::XmlMarkup.new
	xml.rss(:version => "0.91") {
		xml.channel {
			xml.title("Picklez")
			xml.description("Your picklez, foo !")
			midgets.each { |midget|
				xml.item {
					xml.title( midget[:title] )
					xml.link( midget[:link] )
					xml.description( midget[:body] )
				}
			}
		}
	}
end

You have your RSS 0.91 generated and all pretty, just waiting for to be stored somewhere. A number of options present themselves to you now, the main ones being that you either run your script on request as a CGI, or you stick it into a cron task and have it store its results in an XML for you. You could go either way, i chose to go with a cron task that sticks the feed into a file once an hour, because the data i'm intrested in isn't very urgent.

Should you want the source of my awful thief of a script, and together with it the terrible secret of which cartoons i watch, you can find them here

Also, one thing you should note is that in case you're running your script from a shared host and your ruby gems are stored in the local directory, you should probably set the ruby gem home dir in the script before you add your requires and what not.

ENV['GEM_HOME']='/home/#{whatever}/ruby/gems/'