Archive for the '/dev/ruby' Category

Two-weekend website: Applican

Applican A couple of weeks ago, in the middle of getting DreamBank ready for launch I was feeling like I needed a break. Of course that meant “what can I develop in Rails over a single weekend?” See, I had an idea for an application that would fulfill a need we had at DreamBank: how to manage incoming applicants and resumes against available job positions and I was pretty sure it would go.

My one-weekend project became a two weekend project and a bunch more time was shoe-horned in here and there for bug fixes and improvements until it was finally usable. And then we really got serious about the other launch and development got forgotten; it was released and functional and - dare I say it - even useful but neglected.

I now present to you “Applican“, a Rails-based resume/applicant/job tracker designed (as much as it has been) as an internal tool for small & medium-sized companies. For more details see the proto-documentation here.

I consider the current release to be about v0.4: it works, it’s useful, it undoubtedly has bugs, they’re may not be critical, there’s definitely functionality to be added. It’s free, it’s open-sourced, it’s available on Github and it require Rails 2.1.

(Apologies to Robert Rodriguez for stealing and bastardizing one of the best lines in cinema history).

No Comments »

chris on July 13th 2008 in /dev/rails, /dev/ruby

Rails: Won’t Someone Think of the Children?

I have a class, it acts_as_tree. I want to be able to delete nodes from the tree and heal the rift between grandparent and children, joining them as parent-child afterwards.

Seems like it should be pretty obvious but nothing I was coming up with was doing the trick. The node was always deleting yet so were its children. Then I googled upon this forum and the solution was found. When executing a before_destroy filter on a class that acts_as_tree, put the before filter first:

class VettingStage < ActiveRecord::Base
  before_destroy :extract_self_from_chain
  acts_as_tree :foreign_key => “parent_id”, :order => “name”
  …
end

That was easy.

No Comments »

chris on June 24th 2008 in /dev/rails, /dev/ruby

Fun With Ruby, Hash and ||=

A short-circuit (||=) edge case by DABlog is exactly the kind of ‘thinking about code’ that I thoroughly enjoy with Ruby. As simple an exercise as “What does this do to?”

h[:x] ||= 2

leads to an interesting exploration of the difference between || and or, what’s going on behind the scenes with ||= and ultimately made me stop and really think about the situation, though in practical terms this has never been an issue I’ve encountered. It’s just fun to walk through it in irb.

If you’re into Ruby I suggest popping over to read the article through, and do work it out in irb as you go.

Now, my two cents: if I were to read that line of code as-is in a project, I’d expect to end up with an assignment in h for key :x. The reason being:

irb(main):015:0> g
NameError: undefined local variable or method `g' for main:Object
	from (irb):15
	from :0
irb(main):016:0> g ||= 3
=> 3
irb(main):017:0> g
=> 3

Intuitively those two ||= statements seem “same” to me.

1 Comment »

chris on March 25th 2008 in /dev/ruby

Monkey vs. Donkey: Fight!

“I’ve seen things you people wouldn’t believe.” - Roy Batty

One of the things I thoroughly enjoy about Ruby are the linguistic gymnastics it allows developers to pull off. In my brief time with Ruby I have laughed at the cleverness and audacity of more code than any other language I can recall. Not a “ha ha” laugh of mockery or dismay, but one of sheer delight in the truly weird shit that other people tweak out of it.

Rails’ gymnastics with method_missing(), alias() chaining, to_proc() weirdness - clearly that way lies madness! …or does it?

Whether I think the use of those techniques is a good idea or not, or whether I choose to follow down those obscure and dark meta-programming pathways or not is a personal choice of really no consequence at all (unless, perhaps, you have to maintain my code) but that they can be done at all is of significant consequence to all developers. The existence of these features is sufficient to stretch my mind and affect my thinking about how programming languages can and should and do and might work and for that I celebrate them.

It is no small understatement to say that in fifteen years as a developer no other language has instilled in me the joy of simply poking and prodding at it, and following along as others smarter than I poke harder and prod deeper at it, than Ruby has.

“Liberty means responsibility. That is why most men dread it.” - George Bernard Shaw

Of course the black sheep of Ruby meta-programming is so-called “monkey-patching”, a most excellent term if ever there was one.

Oddly enough, when I first heard the term, in the context of Rails, I didn’t fully understand the implications at the time and took monkey-patching to mean simply the dynamic addition of functionality to a class (ie: “adding stuff”) whereas I now correctly understand it to mean both that and the dynamic modification of existing functionality in a class (ie: “screwing with stuff”). Unfortunately for me my first understanding has imprinted itself so deeply to the point where I intrinsically think of monkey-patching as a Good Thing™ and often get caught unawares when someone rips off on a rant against it (that Good Thing is not a statement of absolutism, kindly calm yourself down before firing off a “you’re an idiot because!” comment, those who tend to do so).

Not that I don’t absolutely anti-disagree that screwing with stuff is not a good idea. I am vehemently in the “don’t fuck with established, documented functionality” camp. If your clever gem over-rides my Ruby’s Object#eql? method I’ll cheerfully join the mob and bring my torch (the burny kind, not the battery-operated kind, for my British readers).

But I really enjoy additive monkey-patching. I like that I don’t have to wait for the language designers to decide to incorporate new functionality. I like that I can install a gem and get Integer#even? intrinsic to all my numbers (yes I am aware of how trivial the code to implement that functionality is, thank you very much). I like that sometimes I have to lean back in my chair and think “module or monkey-patch?” before hacking away. It’s a good dilemma to have, this thinking about the fundamental implementation, and implication, of language functionality.

Is monkey-patching over-used? Abused? I don’t know; I honestly don’t have an opinion on that. My experience says less is better so if I had to pick a side I’d tend towards the “monkey-patch as last resort” camp but sometimes it seems to make perfect sense.

But only as an additive.

To deal with this schism in my thinking about monkey-patching I’ve come up with another term for code that screws with established functionality: donkey-patching (the poker plays in the room should get the reference immediately).

If I may steal from the Wikipedia and modify their monkey-patch definition a bit:

A donkey patch (also spelled donkey-patch, DonkeyPatch) is a way to extend or modify established, standard core runtime code without altering the original source code for dynamic languages (e.g. Smalltalk, Javascript, Ruby, Perl, and Python).

A common source of unintended consequence, teeth-nashing, anger and frustration.

A bad idea.

Friends don’t let friends donkey-patch.

2 Comments »

chris on February 27th 2008 in /dev/ruby

FizzBuzz Is Dead, Long Live…?

Chalain has successfully killed FizzBuzz by creating the FizzBuzz Ruby gem:

irb(main):002:0> require 'rubygems'
=> true
irb(main):003:0> require 'fizzbuzz'
=> true
irb(main):004:0> puts fizzbuzz

I have nothing to add to this except: sweet.

Now what?

No Comments »

chris on February 25th 2008 in /dev/ruby

Ruby: 15-second Profanity Filter

In the specification of a current project we have need of a profanity filter. While writing the spec I thought it would be a fun diversion to see how quickly and in how few lines of code a reasonably functional basic profanity filter could be created in Ruby (I don’t actually enjoy writing documentation so I’m easily convinced to do otherwise).

Fear not. The following code won’t see production. I’m aware of how easy it is to circumvent the “protection” and besides the final project will be in PHP, through no fault of Ruby’s. (Don’t even go down that road).

This was originally a one-liner but I couldn’t resist wrapping it in a function and adding in basic (ie: poor) pluralization:

# A bare-bones word ('profanity') filter that checks a string of text for prohibited words
# and returns any that appear in the prohibition list. Also checks for some basic plurals.
# Not intended to be comprehensive, complete, or  particularly expansive. Just hacking.

def filter_profanity( check_str = "", prohibited_words = [] )
  prohibited_words += prohibited_words.map { |w| w + “s” }
  return check_str.downcase.gsub!(/[^a-z]/, ” “).split( ” ” ).uniq!.map { |w| w if prohibited_words.include?( w )  }.compact!
end

# This will spit out a list of the words contained in “str” that aren’t allowed according to “prohibited”
str = “This is a CAT and another cat and some dogs. And parrots too.”
prohibited = ["cat", "dog", "pigeon", "ocelot"]

puts filter_profanity( str, prohibited )

Question: Can the pluralization be worked into it such that the function is once again a one-liner and is still readable by the average Rubyist? I haven’t figured out a way but….

Update: Seems like this might benefit mightily from the inclusion of Jeremy McAnally’s acts_as_good_speeler Rails plugin. Implementation is left as an exercise for the compulsive-obsessive reader.

No Comments »

chris on February 6th 2008 in /dev/ruby

Zed Shaw on Mongrel at QCon

Thoroughly enjoyable talk by Zed Shaw about the history and economics of Mongrel: Mongrel, 2500 Lines, and Economics.

Well worth watching if any of the proper nouns in the sentence above are familiar to you.

No Comments »

chris on February 4th 2008 in /dev/ruby

JSun Runs JRails on JRuby

I find it pretty cool that Sun is already able to run Rails on JRuby, and actually is doing so in production according, to Igor Minar:

…I suggested that we could try to rewrite the app in Rails and deploy it in a regular Java web container, thanks to JRuby and Goldspike. It took some time for Rama to give us a go-ahead, but finally in late September, two other colleagues (with no Rails or JRuby experience) and I started to work on the rewrite alongside our other projects (forums.sun.com and wikis.sun.com).

The ability to access and seamlessly integrate with existing or new Java code is a huge plus without which we would not have been able to launch this project successfully

The site in question is mediacast.sun.com.

That’s eating your own dog food.

I am very impressed by the speed with which JRuby seems to be coming along, a perception born of notable milestones like this and the continued updates that Charles Nutter posts to the ruby-talk mailing list. I like it.

No Comments »

chris on January 29th 2008 in /dev/ruby

MachSpeedCalc on RubyForge

My Mach speed calculation Ruby library is finally up on RubyForge: machspeedcalc. It provides means to convert between Km/h and Mach and Miles/h and Mach (and vice versa) like so:

      => m = MachSpeedCalulator.new
      => mach_speed = m.kmh_to_mach( 120, 25 )
      => 0.0962977998319029

A bit esoteric, this I realize, but I had a need.

As this lib is only one file I haven’t packaged it at all. Jump to the Svn repo here.

No Comments »

chris on January 19th 2008 in /dev/ruby

A Method That Knows Its Own Name: this_method()

I realize this is the second mailing list-mining for content this week but this was too cool to not mention. Over in Ruby Forum in using the current method name within current method Aleks Kissinger, Robert Klemme, and Matt Todd hashed out a way for methods in Ruby 1.8 to know their own identity.

To jump to the end, the final solution is:

module Kernel
private
   def this_method
     caller[0] =~ /`([^']*)’/ and $1
   end
end

As an example:

class TestClass
   def this_methods_name
      puts this_method
   end
end

t = TestClass.new
t.this_methods_name

Pretty cool stuff, that.

No Comments »

chris on January 14th 2008 in /dev/ruby