Rewriting My Competitors

It’s really clear that the polls So Play We All are measuring progress. When we have a quiet week, there’s a lot fewer votes. This week, there were 4, evenly split between Luke and I. The SPWA site doesn’t have code to handle ties so it highligted me as winning, which I guess means the bugfix is not my problem. :)

Luke laid down code for cards. I know I’m helping the enemy, but I’ve got to tweak it. His code is:

 
class CardController < ApplicationController
  def play
    play_sym = "play_#{@card}".intern # PH: this should be .to_sym
    self.send(play_sym)
    render :action => play_sym and return
  end
 
  def pocket
    pocket_sym = "pocket_#{@card}".intern
    self.send(pocket_sym)
  end # PH: no explicit render here? Feels like a paste error
 
  protected
 
  # plays
  def play_roland
    # Play the game to see what happens when you play the Roland card!
  end
 
  def play_water
    # Play the game to see what happens when you play the Water card!
  end
 
  # pockets
  def pocket_roland
    # Play the game to see what happens when you pocket the Roland card!
  end
 
  def pocket_water
    # Play the game to see what happens when you pocket the Water card!
  end
 
end
I’d write this code as:
 
class CardController < ApplicationController
  # I'm guessing from usage above @card is just the name for a card as a string
  # and that it's loaded from the url by a filter, note that I use it differently.
  before_filter :load_card
  after_filter :default_render_card
  
  def play
    @card.play
  end
 
  def pocket
    @card.pocket
  end
 
  protected
 
  def load_card
    @name = params[:card]
    @card = "card/#{@name}".camelize.constantize
  end
 
  def default_render_card
    render :template => "cards/#{request.action}/#{@name}" unless performed?
  end
end
 
# add in config/application.rb:
module Oaqn
  class Application < Rails::Application
    config.autoload_paths += %W(#{config.root}/app/cards)
  end
end
 
# and then create app/cards/roland.rb:
module Card
  module Roland
    def pocket
      # code for pocketing
    end
 
    def play
      # code for playing
    end
  end
end

So now the cards each get a source file to themselves, templates have their own per-action dirs (better swapped to per-card dirs, if there are more actions), there’s less duplicated code, and it’s far easier to test these smaller pieces. The only thing missing from this example is the fact that Luke may have to pass some game state into the methods. As long as there’s not too much it’s probably worth being explicit about.

2011-07-09: Luke actually used this code and found it didn’t work as written. I found an explanation; either add ‘app’ to autoload_paths instead of ‘app/cards’, or drop the Card wrapper.

Meanwhile, in the past, Jim wrote some PHP, and I’m not touching that language.

No, in seriousness, Jim talked about why he has some identifiers surrounded by __ (which I’d called python poisoning). I haven’t dug into his code (again, PHP), but it looks like it might be an InBandSignal to reuse Events as framework steps.

And then he talks about session fixation attacks, which are have been protected against out-of-the-box on PHP with the session.use_only_cookies setting for a while. I was a bit confused, I’m pretty sure he’s actually describing session capture attacks. Oh, and there was some other stuff about writing code to store sessions in the database. If you’re curious, Jim, here’s the code for a Rails app to do that, which appears commented-out in the stock config file for your editing convenience:

 
  Oaqn::Application.config.session_store :active_record_store

It includes support out of the box for keeping sessions in cookies (encrypted, of course), your SQL database via ActiveRecord, or Memcached. I’m curious, how much of your budget did you spend storing sessions?

Want more? I'm not as good at forgetting to update @pushcx on Twitter.