Posted: May 20th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 1 Comment »
I have the following in a rake task run every 30 minutes. You’ll need jnunemaker’s twitter gem.
Follow your followers in Ruby
require 'twitter'
# Check out the twitter gem docs for using oauth
httpauth = Twitter::HTTPAuth.new("username", "password")
base = Twitter::Base.new(httpauth)
to_follow_ids = base.follower_ids - base.friend_ids
unavailable_count = 0
to_follow_ids.each do |tfid|
begin
base.friendship_create(tfid, true)
rescue Twitter::General
# Twitter::General is raised for 403 errors
# Which occur when you're trying to follow someone who's been banned by twitter
base.block(tfid)
rescue Twitter::Unavailable
# Wait and try again if twitter's telling you to wait
sleep 5
if unavailable_count < 3
retry
unavailable_count += 1
end
end
end
Posted: May 10th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 4 Comments »
Recently I fell victim to the Twitter-Mash / Extlib-DataMapper-Mash namespace collision. To get around this problem, I’ve created a new gem, Aikidoka.
Here’s what happened when I tried to use Twitter when Extlib had already been loaded:
irb(main):001:0> require 'Twitter'
=> ["Twitter"]
irb(main):002:0> Twitter::Search.new("bokken").fetch
SystemStackError: stack level too deep
Here’s what happens when you use Aikidoka:
irb(main):001:0> require 'aikidoka'
=> ["Aikidoka"]
irb(main):002:0> Aikidoka.rename("Mash" => "Twitter::Mash"){require 'twitter'}
=> ["Mash"]
irb(main):003:0> Twitter::Search.new("aikidoka").fetch
=> <Mash completed_in=0.052875 max_id=1754360060 next_page="?page=2&max_id=1754360060&q=aikidoka"
etc...
It works! What this does is namespace the Mash defined when I require the Twitter gem, so that Mash is now Twitter::Mash. Also, Extlib’s Mash is still there, untouched, so you don’t need to worry about that. Here’s how Aikidoka does its magic:
- It temporarily renames existing constants so that they don’t get clobbered. In this case, “Mash” is renamed to “AikidokaMash”. Right now this only works with top-level constants.
- It yields to the given block. This block should define the constants you want permanently renamed/namespaced. In this case, we’re requiring “twitter”, which in turn requires “mash”. “mash” defines the constant we want to rename, Mash.
- It creates modules as necessary to create the namespace. In this case, the module Twitter is already defined so that’s used. However, if we wanted to rename “Mash” to “Potatoes::Mash”, then a module named “Potatoes” would have been created.
- It assigns the object referred to by the old constant to its new constant. “Twitter::Mash” now refers to the same object that “Mash” refers to.
- Old constants are removed to clean up the namespace. The constant “Mash” no longer exists, the object it used to refer to lives on.
- The constants temporarily renamed in step 1 are now given their original names back. Extlib’s “Mash” is no longer “AikidokaMash”; it’s “Mash” again.
The code is very simple - a total of 67 lines in one file with decent specs - so hopefully it’s easy to dig into.
Right now Aikidoka is best at nesting an existing top-level constant within another constant of a different name. I haven’t tried doing something like Aikidoka.rename("Mash" => "Mash::Twitter") or Aikidoka.rename("ActiveRecord::Base" => "ARBase"), and those examples probably wouldn’t work.
All in all, it does what I want it to and seems to work OK :) You can install it with “gem install flyingmachine-aikidoka“. If you’re wondering about the name, aikido is a martial art designed to resolve conflict harmoniously, and an aikidoka is a student of aikido.
Posted: May 7th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 1 Comment »
I’ve forked jnunemaker’s twitter and updated to use peterpunk’s Mhash gem instead of the Mash gem it was using. This avoids the namespace collision with Mash in datamapper’s extlib library.
http://github.com/flyingmachine/twitter/tree/master
git://github.com/flyingmachine/twitter.git
Posted: April 23rd, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 1 Comment »
FiveRuns Tuneup for Merb didn’t work out of the box for me. The following patch to the gem got it working:
Patch for Fiveruns Tuneup on Merb 1.0.11
diff -r fiveruns_tuneup_merb-0.5.3/lib/fiveruns_tuneup_merb/instrumentation.rb fiveruns_tuneup_merb-0.5.3.updated/lib/fiveruns_tuneup_merb/instrumentation.rb
170c170
< FiverunsTuneupMerb::Instrumentation.format_sql(query, adapter.send(:update_statement, query), attributes),
---
> FiverunsTuneupMerb::Instrumentation.format_sql(query, adapter.send(:update_statement, attributes.keys, query), attributes),
diff -r fiveruns_tuneup_merb-0.5.3/lib/fiveruns_tuneup_merb.rb fiveruns_tuneup_merb-0.5.3.updated/lib/fiveruns_tuneup_merb.rb
5,6c5,6
< load_dependency 'merb-slices'
< load_dependency 'fiveruns_tuneup_core'
---
> load_dependency 'merb-slices', nil
> load_dependency 'fiveruns_tuneup_core', nil
Posted: April 8th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 3 Comments »
Overview
I’ve been trying to make merb a little bit easier to use by implementing form element classes. The approach I’ve taken is influenced by my experience with Cocoa. The view classes I’ve created encapsulate behavior for displaying complex form elements and for parsing the data sent to controllers by the form elements.
One great advantage that Cocoa development has over web development with an MVC framework like merb is that your views are first-class objects and can be communicated with directly using the same language as the rest of the system. With a web app, you have to go to extra lengths so that your Model or Controller will correctly get data from a form element if the element is even slightly complex. Most likely you’ll need to use Javascript in addition to whatever backend language you’re using. You’ll probably also have a lot of code to parse those elements in your controllers, spreading the concept your form element represents all over the place. In Cocoa, interacting with complex “form elements” is easier and cleaner.
Brief Cocoa Example
One iPhone app I’m on working on stores a time interval in seconds. Since it’s not very user-friendly to make a user figure that out, I use a picker that allows him to specify days, hours, and minutes.

This picker is an instance of a subclass of UIPickerView, which means it’s a first-class object and I can define methods on it to get at its tasty insides. The advantage here is that methods that belong together conceptually are placed together physically. The salient method is below:
picker valueInSeconds
- (NSInteger)valueInSeconds
{
NSInteger dayRow = [self selectedRowInComponent:0];
NSInteger hourRow = [self selectedRowInComponent:1];
NSInteger minuteRow = [self selectedRowInComponent:2];
NSInteger daySeconds = dayRow * 24 * 60 * 60;
NSInteger hourSeconds = hourRow * 60 * 60;
NSInteger minuteSeconds = minuteRow * 5 * 60;
return (daySeconds + hourSeconds + minuteSeconds);
}
Therefore when I’m ready to set the time interval, I just do the following:
medication.interval = [intervalPicker valueInSeconds];
From what I understand, this is all nothing special in Cocoa development.
The Web App Problem
merb (and Rails) have no mechanism for treating form elements as objects. Form elements are displayed using javascript, templates, and helpers. Then their data is sent to a controller as a hash. They’re usually parsed with code in the controller.
For example, traineo.com we have the following form elements:


For these form elements, we use javascript to change the weight input when the user clicks a radio button.
Initially, we had some code in our controller to get the “weight” value and convert it to kilograms so that we could then pass it to a model. Something like
if (params[:weight_input]["stone"])
# Convert from stone to kg
elsif (params[:weight_input]["american"])
# Convert from lbs to kg
else
# Leave as is; already in kg
This worked ok, but once we started placing the weight input fields in other forms, the code had to be improved. We could have created a method in ApplicationController for parsing date input, but it didn’t seem like good OO programming to make ApplicationController aware of and responsible for one set of form fields. Better to make a class and take advantage of Ruby’s object goodness.
Enough of my blathering - here’s the code:
merb widget
# lib/widgets/widget.rb
# Superclass for our form element "widgets"
class Widget
include Merb::GlobalHelpers
# This is necessary to include Merb::GlobalHelpers
class_inheritable_accessor :_default_builder
# These are for convenience
attr_accessor :params
attr_accessor :session
def initialize(params = {}, session = {})
self.params = params
self.session = session
end
def value
end
end
# lib/widgets/weight_input_switcher.rb
class WeightInputSwitcher < Widget
attr_accessor :attribute_name, :weight_in_kg, :unit_preference
# View methods
def setup(attribute_name, weight_in_kg = nil, unit_preference = session[:unit_preference])
self.attribute_name = attribute_name
self.weight_in_kg = weight_in_kg
self.unit_preference = unit_preference
self
end
def switcher
html = "<div class='weight_input_switcher'>"
html += weight_input("lbs")
html += weight_input("kg")
html += weight_input("st")
html += "</div>"
html
end
def weight_input
html = "<span class='weight_input #{unit_preference}'>"
html += weight_input_field
html += "</span>"
end
def weight_input_field
if unit_preference == "st"
stone, lbs = if weight_in_kg.to_i == 0
["",""]
else
weight_input_value(weight_in_kg, unit_preference).split(" st ")
end
html = text_field attribute_name, :value => stone, :name => "weight_input[stone]", :class => "weight_input_field stone"
html += "<span class='weight_unit'>stone</span>"
html += text_field attribute_name, :value => lbs, :name => "weight_input[lbs]", :class => "weight_input_field stone lbs"
html += "<span class='weight_unit'>lbs</span>"
else
value = weight_input_value(weight_in_kg, unit_preference)
html = text_field attribute_name, :value => value, :name => "weight_input", :class => "weight_input_field"
html += "<span class='weight_unit'>" + unit_preference.to_s + "</span>"
end
html
end
# Parse methods
# We kinda cheat here and use params. Need to figure out a better way to do this.
def value
if params["weight_input"]["stone"]
"#{params["weight_input"]["stone"]} st #{params["weight_input"]["lbs"]} lbs"
else
"#{params["weight_input"]} #{Units.weight_full_to_abbreviation_map[unit_preference]}"
end
end
private
def weight_input_value(weight_in_kg, unit_preference)
begin
weight_in_kg.to_display_weight_without_unit(unit_preference)
rescue
""
end
end
end
# The following is added to global_helpers.rb
def widget(klass, *args)
klass.new(params, session).setup(*args)
end
# An example of using the "Widget" to display form elements
widget(WeightInputSwitcher, :weight, @current_user.current_weight).switcher
# An example of using the "Widget" to get the value of form elements
weight_widget = widget(WeightInputSwitcher, :weight, 0, "", user[:unit_preference])
weight = weight_widget.value
So my code could use some improvement, but I think it lays some good groundwork for treating form elements as objects in Merb. Any feedback would be greatly appreciated!
Posted: December 31st, 2008 | Author: Daniel Higginbotham | Filed under: Uncategorized | No Comments »
Don’t wait until you “feel like it” to do something
In fact, doing the thing usually puts you in the right mood to be doing it.I learned this one when my uncle moved from Boston to New Jersey. Before, he was a 45 minute drive away. Now, I’d have to travel at least 4 hours to see him. I regret that I hadn’t gone to see him more, even though I didn’t always feel like it.
Everything will take longer than you expect it to
Well, almost everything. Phone calls that should take 5 minutes will take 20. Errands that you think will take one hour will take two. Even when you think you’ve learned and adjusted your expectations, things will still take longer. This one hit me when my friend, my girlfriend, and I drove to downtown Boston to see a friend perform. We should have been 10 minutes early, but we couldn’t find a parking spot and arrived a little late. This lesson was confirmed recently when I left 30 minutes early to go to an aikido class and ended up 5 minutes late because of unexpected traffic.
There’s no reason to worry
Are you worried that something bad is going to happen? Well something bad IS going to happen, so how’s worrying going to make any difference? Besides, worrying will drain your resources prematurely and make it harder for you to cope. I learned this one from getting laid off twice in three months.
What it means
Around the time that I got laid off for the second time, I was listening to the Alan Watts podcast a lot. He talks mostly about buddhism and mentioned that “nirvana” means “breathe out” - as in, if you hold your breath, you’ll suffocate. In the same way, if you cling to life, you’ll “suffocate”. But if you breathe out, your breath will come back to you, and it works the same with life.
I try to keep this in mind when I have too much inertia to do something, when I’m becoming impatient because something’s taking longer than I expected, or when I find my energy being drained by worry.
Posted: December 2nd, 2008 | Author: Daniel Higginbotham | Filed under: Merb, Programming | 1 Comment »
I ran into a couple snags when upgrading, but doing the following solved my problems:
- updating the do_mysql gem
- updating the do_sqlite3 gem
- installing dm-core from source (solves the problem described here)
- git clone git://github.com/sam/dm-core.git
- cd dm-core
- rake package
- sudo gem install pkg/dm-core-0.9.7
Posted: November 29th, 2008 | Author: Daniel Higginbotham | Filed under: Projects | 1 Comment »
I wrote the following for Happy Job Search.
In August I got laid off because the startup I was working for was running out of funds. After getting a new job, I got laid off again in October, for the same reason. The first time was distressing to the point where I began to feel general anxiety - I would be sitting doing nothing and I would still feel a lot of anxiety. The second time around I handled the fallout and the job search much better, to the point where it was even fun. Here are some practices that worked well:
1. Unwind.
The first time I got laid off I immediately started to freak and start to look for new jobs. Half of the emails I sent didn’t have a resume attached. My cover letter was sloppy.
The second time I went out and got some dinner with my girlfriend and watched a movie. I was able to approach my situation much more objectively afterwords.
If you immediately get frantic or distraught, it’s hard to get yourself out of that place. Getting yourself in the right frame of the mind at the beginning will allow you to approach your job search with calmness.
2. Ask for help.
The first time I got laid off I tried to deal with everything myself. The result that was I felt like no one cared (surprise!). Having to struggle with that on top of everything else made me miserable.
The second time I immediately talked to my girlfriend about it, and talked to a couple friends soon after. I asked my friends to see if they knew anyone who needed a web developer. I didn’t get any referrals from them, but it was nice to feel cared for.
Looking back, the reason I tried to handle it myself the first time was because I felt ashamed. I pride myself on my work (and my ability to take care of my girlfriend, who is chronically ill), so getting laid off was a blow to my ego in a way. There’s no reason to feel this way, though.
3. Exercise.
I actually got this right the first time. Exercise helps freaking everything. It helped reduce my anxiety and it gave me more energy. It also gave me a feeling of accomplishment.
A great book
has recently been written on the incredible benefits of exercise, and if you don’t already have a regimen I recommend you read it.
4. Get organized
Getting organized allowed me to feel in control. The first time, I was pretty haphazard in my approach to searching for jobs and following up. The result was that I felt constant anxiety because I wasn’t sure what I needed to next. I also didn’t have any clear way to see what I was accomplishing in my job search, so I never felt OK with the effort I was putting forth.
I created this web site to help me get organized, and using it helped reduce my anxiety. In addition to this site, here are a couple lists I used to get organized:
- Job checklist - what do with each application
- “Things I can do” - a list I made of possible projects to enhance my marketability and possibly provide revenue. I picked one major one (working on this site) and focused on it.
5. Always have something to move forward on.
The real benefit of getting organized was that I always had something to move forward on. This helped keep me from dwelling on rejections and it kept me motivated and excited. This was a huge improvement from the first layoff, where I was basically a mess :)
All of these practices helped me cope better. If you have any techniques that worked for you, please email them to me!
Posted: September 6th, 2008 | Author: Daniel Higginbotham | Filed under: Programming, Rails | 6 Comments »
The following allows you to get rid of the numerous “Model.find(params[:id])” calls in your controllers. I’m pretty sure I’ve seen similar solutions out there, so if anyone wants to link to those in the comments that’d be helpful.
Read the rest of this entry »
Posted: September 1st, 2008 | Author: Daniel Higginbotham | Filed under: Javascript, Programming | No Comments »
function remove_defaults(){
$("input[@type=text]")
.each(function(){
this.default_value = this.value
})
$("input[@type=text]")
.focus(function(){
if(this.value == this.default_value) {
this.value = ""
}
})
.end()
}
$(remove_defaults)