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 | No Comments »

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.


Upgrading from Merb 1.0 to 1.0.3

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

What I’ve Learned from Getting Laid Off Twice in Three Months

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!


DRY up controllers with params_to_objects

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 »


jquery: Remove Default Text Values on Focus

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)