Follow your Followers using Ruby

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

  1. require 'twitter'
  2. # Check out the twitter gem docs for using oauth
  3. httpauth = Twitter::HTTPAuth.new("username", "password")
  4. base = Twitter::Base.new(httpauth)
  5. to_follow_ids = base.follower_ids - base.friend_ids
  6. unavailable_count = 0
  7. to_follow_ids.each do |tfid|
  8.   begin
  9.     base.friendship_create(tfid, true)
  10.   rescue Twitter::General
  11.     # Twitter::General is raised for 403 errors
  12.     # Which occur when you're trying to follow someone who's been banned by twitter
  13.     base.block(tfid)
  14.   rescue Twitter::Unavailable
  15.     # Wait and try again if twitter's telling you to wait
  16.     sleep 5
  17.     if unavailable_count < 3
  18.       retry
  19.       unavailable_count += 1
  20.     end
  21.   end
  22. end


Aikidoka Prevents Ruby Namespace Collisions

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Old constants are removed to clean up the namespace. The constant “Mash” no longer exists, the object it used to refer to lives on.
  6. 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.


Twitter and Datamapper fix

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


Patch for Fiveruns Tuneup on Merb 1.0.11

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

  1. 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
  2. 170c170
  3. <                  FiverunsTuneupMerb::Instrumentation.format_sql(query, adapter.send(:update_statement, query), attributes),
  4. ---
  5. >                  FiverunsTuneupMerb::Instrumentation.format_sql(query, adapter.send(:update_statement, attributes.keys, query), attributes),
  6. 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
  7. 5,6c5,6
  8. <   load_dependency 'merb-slices'
  9. <   load_dependency 'fiveruns_tuneup_core'
  10. ---
  11. >   load_dependency 'merb-slices', nil
  12. >   load_dependency 'fiveruns_tuneup_core', nil


Form Element Objects in Merb

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.

Picker for 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

  1. - (NSInteger)valueInSeconds
  2. {
  3.         NSInteger dayRow = [self selectedRowInComponent:0];
  4.         NSInteger hourRow = [self selectedRowInComponent:1];
  5.         NSInteger minuteRow = [self selectedRowInComponent:2];
  6.         NSInteger daySeconds = dayRow * 24 * 60 * 60;
  7.         NSInteger hourSeconds = hourRow * 60 * 60;
  8.         NSInteger minuteSeconds = minuteRow * 5 * 60;
  9.        
  10.         return (daySeconds + hourSeconds + minuteSeconds);
  11. }

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:

American units, weight in lbs

British units, weight in stone

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

  1. # lib/widgets/widget.rb
  2. # Superclass for our form element "widgets"
  3. class Widget
  4.   include Merb::GlobalHelpers
  5.  
  6.   # This is necessary to include Merb::GlobalHelpers
  7.   class_inheritable_accessor :_default_builder
  8.  
  9.   # These are for convenience
  10.   attr_accessor :params
  11.   attr_accessor :session
  12.  
  13.   def initialize(params = {}, session = {})
  14.     self.params = params
  15.     self.session = session
  16.   end
  17.  
  18.   def value
  19.   end
  20. end
  21.  
  22. # lib/widgets/weight_input_switcher.rb
  23. class WeightInputSwitcher < Widget
  24.   attr_accessor :attribute_name, :weight_in_kg, :unit_preference
  25.  
  26.   # View methods
  27.   def setup(attribute_name, weight_in_kg = nil, unit_preference = session[:unit_preference])
  28.     self.attribute_name = attribute_name
  29.     self.weight_in_kg = weight_in_kg
  30.     self.unit_preference = unit_preference
  31.     self
  32.   end
  33.  
  34.   def switcher
  35.     html = "<div class='weight_input_switcher'>"
  36.     html += weight_input("lbs")
  37.     html += weight_input("kg")
  38.     html += weight_input("st")
  39.     html += "</div>"
  40.     html
  41.   end
  42.  
  43.   def weight_input
  44.     html = "<span class='weight_input #{unit_preference}'>"
  45.     html += weight_input_field
  46.     html += "</span>"
  47.   end
  48.  
  49.   def weight_input_field
  50.     if unit_preference == "st"
  51.       stone, lbs = if weight_in_kg.to_i == 0
  52.         ["",""]
  53.       else
  54.         weight_input_value(weight_in_kg, unit_preference).split(" st ")
  55.       end
  56.  
  57.       html = text_field attribute_name, :value => stone, :name => "weight_input[stone]", :class => "weight_input_field stone"
  58.       html += "<span class='weight_unit'>stone</span>"
  59.       html += text_field attribute_name, :value => lbs, :name => "weight_input[lbs]", :class => "weight_input_field stone lbs"
  60.       html += "<span class='weight_unit'>lbs</span>"
  61.     else
  62.       value = weight_input_value(weight_in_kg, unit_preference)
  63.      
  64.       html = text_field attribute_name, :value => value, :name => "weight_input", :class => "weight_input_field"
  65.       html += "<span class='weight_unit'>" + unit_preference.to_s + "</span>"
  66.     end
  67.     html
  68.   end
  69.  
  70.   # Parse methods
  71.   # We kinda cheat here and use params. Need to figure out a better way to do this.
  72.   def value
  73.     if params["weight_input"]["stone"]
  74.       "#{params["weight_input"]["stone"]} st #{params["weight_input"]["lbs"]} lbs"
  75.     else
  76.       "#{params["weight_input"]} #{Units.weight_full_to_abbreviation_map[unit_preference]}"
  77.     end
  78.   end
  79.  
  80.   private
  81.   def weight_input_value(weight_in_kg, unit_preference)
  82.     begin
  83.       weight_in_kg.to_display_weight_without_unit(unit_preference)
  84.     rescue
  85.       ""
  86.     end
  87.   end
  88. end
  89.  
  90. # The following is added to global_helpers.rb
  91. def widget(klass, *args)
  92.   klass.new(params, session).setup(*args)
  93. end
  94.  
  95. # An example of using the "Widget" to display form elements
  96. widget(WeightInputSwitcher, :weight, @current_user.current_weight).switcher
  97.  
  98. # An example of using the "Widget" to get the value of form elements
  99. weight_widget = widget(WeightInputSwitcher, :weight, 0, "", user[:unit_preference])
  100. 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!


Some Things I Learned in 2008 (That Hopefully I won’t Have to Re-Learn in 2009)

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.


Usability Embodied

Posted: August 24th, 2008 | Author: Daniel Higginbotham | Filed under: Uncategorized | No Comments »

A few years ago I ordered DSL service. The DSL modem came with an ethernet cable, and one end was labeled “this end goes in your computer”, and the other was labeled “this end goes in the modem.” Obviously, it doesn’t matter which end goes where, but the labels undoubtedly eliminated any possible confusion.


Robots!

Posted: July 14th, 2008 | Author: Daniel Higginbotham | Filed under: Uncategorized | No Comments »

I’ve been learning more about electronics, in part to get a ground-up understanding of computers. In the process I’ve become interested in learning to build robots.

My first attempt at building a robot, about 8 years ago, wasn’t really successful. I was in high school and I wanted to build a robot that would turn off my light switch across the room because at night I would read in bed, and when I was done I didn’t want to have to get up to turn off the light. So I got my mom to buy me Lego Mindstorms one Christmas and put together a robot, and it would just run into the wall and fall apart. I tried a little more and kept getting the same result, so I just said “fuck it” and I bought a lamp to put beside my bed. Incidentally, that’s still how I approach problems most of the time.

Anyway, one thing I’d like to make is a little wristband with an LCD (like a digital watch) displays random words throughout the day. After that, a robot parrot which repeats words it hears often. It’ll have Barry White’s voice.


Woz’s Calling

Posted: July 11th, 2008 | Author: Daniel Higginbotham | Filed under: Uncategorized | No Comments »

Normally I don’t watch TV, much less blog about it, but last night on “My Life on the D-List” they showed Steve Wozniak, billionaire inventor of the personal computer, bragging about how many Kathy Griffin t-shirt he sold at a convention for bears (not the animal - big, burly, gay men). Hilarious.

They also showed Woz going to a “bear maul” (a bazaar for big burly gay men paraphernalia), picking up a whip and saying, “This must be a movie prop.” I tried to find a clip, but only found this lousy 2 minute piece from bravo. It does show Woz briefly at the beginning of the clip.