Tuesday, March 22, 2011

Inspired

I've been reading way more than writing lately, and my current favorite blogger has got to be Alan Skorkin. In particular, I'm a fan of two of his articles, one on the value of fundamentals, and one on the "I'll learn it when I need it" attitude. I love his writing, but more importantly, I'm convicted by his arguments.

With respect to these points, I'm making it a point to encourage my growth at least a little each day, starting right now by taking Alan's advice from the former article and exploring the API of the Array class in Ruby (a class probably used more often than any other in my day to day work). See my next post for anything I might learn...

Monday, November 22, 2010

Tag-it 0.3.1 is released!

If you've been a consistent reader, you know that last month I released a new gem called "tag-it" to interface with RFID receivers and the tags that come into range with them. Today, there's a new version with a new feature.

In version 0.2.x, there was 1 primary class for continually monitoring a port for tag events. This doesn't do everything I wanted though, because in some cases I really just needed to know what tags were in range at one precise instant. The long-running class really wasn't a good fit, so there's a new class available called TagIt::TagSnapshot which has a "shoot!" method that returns an array of the tag-names currently found:

  require "tag_it"
  port = SerialPort.new("/dev/tty.yourport",{:baud=>9600})
  snapshot = TagIt::TagSnapshot.new(port)
  tags = snapshot.shoot!
  # => ["1nri","1okD","1nrP"]
Get the latest:

  gem install tag-it

Tuesday, November 16, 2010

json (_pure) ruins my morning

wrong argument type JSON::Pure::Generator::State (expected Data)

This is what I saw staring back at me from my console this morning when I checked out a project and ran my specs. Specs that had been passing just fine yesterday. The only thing I could think of was that I had added a couple new gems to my gem file, but since I hadn't used them yet surely they couldn't be breaking my test suite?

Well, if you've been a coder for any length of time, by now you should know that the likelihood of a given event contributing to your code failure is inversely proportional to your initial index of suspicion of it's relation.

Fortunately, I didn't have to search long. Googling for "wrong argument type JSON::Pure::Generator::State" quickly turned up this blog post on prettystatemachine that explains the problem. Those gems I'd added? One had "json_pure" as a dependency, so I'll include my own brief version for reference:

ActiveSupport and json_pure both hook into the "to_json" method. ActiveSupport defines to_json for many simple types, but expects fixnum's "to_json" to be handled by Object. json_pure is intercepting that call and not getting the data it wants. Defining "to_json" on fixnum seems to solve the problem.

Hence, I've created an initializer in my rails app called "./initializers/json_patch.rb" and put the following code in it:


class Fixnum
  def to_json(options = nil)
    to_s
  end
end

Specs pass. I would thank "prettystatemachine" by name, but I can't find any reference to the author of the blog. Whoever you are, thanks man.

Saturday, November 13, 2010

Hello node

I've been playing a bit with node.js recently, but have had trouble getting my friends to try it out. They hate javascript, can't see how this framework is any different, won't even give it a look, and further more evented programming sucks.

Well, everyone is entitled to their opinion, but you can't really have a valid opinion without the information. Node.js and other event driven models (EventMachine in ruby, etc) are going to continue to be a huge deal as more applications require more realtime information to be pushed between client and server, let's at least know a little about the tools that are probably carrying the future on their actively-under-development shoulders.

In this spirit, I've put together a very simple "hello world" application in Express (web framework for node.js), available on my github profile here: Hello Node

You see how nice I am? You don't even have to write your own hello world, I just did it for you, all you have to do is check out the code and read through all 4 files therein to get a feeling for why this new tool really isn't all that unfamiliar compared to whatever web framework you're working with now. No fan-boy over-hyped blog post about it's infinite scalability, no drooling and sobbing over how wonderful it is, just a few blocks of harmless code that wants to be your friend. Still hate everything about it? Fine, but at least you'll have some ground to stand on from legitimately having taken a look.

Testing Heroku's SMS addon with Cucumber

(UPDATE: All code on this page is also available as a gist here: GIST)

I love Heroku's add-ons.

I love Cucumber testing.

But I sometimes hate putting the two together.  How do you test the infrastructure you don't know much about?  I've been confronted with this recently with the "moonshado-sms" addon, which is a super-simple way to hook your application up to a cheap sms gateway.  My integration tests were difficult, though.  How do I check that everything got sent appropriately?  That the SMS went to the right person, with the right number, and the right message?

I stumbled a bit, but came up with something that I think is pretty clever, and I'm going to share it here in case you have the same insatiable desire to see a series of green dots before deploying that I do.  In my env.rb file (for cucumber), at the bottom, I include some monkey patching of Moonshado's API:



module Moonshado
  class Sms
    cattr_accessor :sent_messages
   
    def deliver_sms
      raise MoonshadoSMSException.new("Invalid message") unless is_message_valid?(@message)

      data = {:sms => {:device_address => format_number(@number), :message => @message.to_s}}

      self.class.sent_messages ||= []
      self.class.sent_messages << data
      response = RestClient::Response.create('{"stat":"ok","id":"sms_id_mock"}', "", {})

      parse(response.to_s)
    rescue MoonshadoSMSException => exception
      raise exception
    end
  end
end

Now mix in some clever step defenitions with "sms_steps.rb" in your cucumber "step_definitions" folder:

When /^the sms message "([^"]*)" is sent to "([^"]*)"$/ do |number, message|
  Moonshado::Sms.new(message,number).deliver_sms
end

Then /^there should be an SMS sent to "([^"]*)" saying "([^"]*)"$/ do |number, sms_text|
  messages = Moonshado::Sms.sent_messages
  messages = Moonshado::Sms.sent_messages.select{|data| 
    data[:sms][:device_address] == number and data[:sms][:message] == sms_text
  }
  messages.size.should == 1
  messages.each{|msg| Moonshado::Sms.sent_messages.delete(msg)}
end

Then /^there should be no SMS messages sent$/ do 
  if Moonshado::Sms.sent_messages
    Moonshado::Sms.sent_messages.size.should == 0
  end
end

Take and edit for your own purposes, and may your code always be well tested.

(PS: All code on this page is also available as a gist here: GIST)