Archive for the ‘Ruby’ Category

GUID/UUID in Ruby

Monday, May 15th, 2006

Surprisingly Ruby doesn’t come with a built in GUID generator. Thankfully there is the useful uuid project which implements a gem that you can easily install and use to generate GUIDs.

1. gem install uuid

2. require 'uuid'

3. UUID.new

Gems rock.

Dynamic is hot

Friday, May 12th, 2006

Oh one just has to adore the dynamic nature of Ruby coupled with the thoughtfulness of Rails.

I have a Feedtag object which has feed_id and tag_id members. Naturally with Rails you get to be able to find records using Feedtag.find_by_tag_id and Feedtag.find_by_feed_id. But what if you wanted to use both Ids to find a record?

No problem. Just use Feedtag.find_by_tag_id_and_feed_id. It is a bit of a mouthful but it works. No extra code, no SQL strings, just a bit of beautiful dynamic code.

Literally Ruby

Thursday, May 11th, 2006

I’ve long been a double-quote user and thought it odd that languages supported both that and a single-quote for string literals. Ruby though is a bit clever. A single-quote e.g. ‘literal text’ tells Ruby not to waste time looking inside the string. Double-quotes e.g. “Hello {#name}” tells Ruby that you want it to interpret the contents. In this case Ruby will replace #name with the variable’s value.

A dirty Ruby

Wednesday, May 10th, 2006

if soapResponse.getNewTagsSinceResult.respond_to? "tag"
 if soapResponse.getNewTagsSinceResult.tag.is_a? Array
  for tag in soapResponse.getNewTagsSinceResult.tag
   @tag = Tag.find_by_sync_id(tag.id)
   if (@tag)
    @tag.name = tag.name
    @tag.save
   else
    @tag = Tag.new
    @tag.name = tag.name
    @tag.sync_id = tag.id
    @tag.save
   end
  end
 else
  tag = soapResponse.getNewTagsSinceResult.tag
  @tag = Tag.find_by_sync_id(tag.id)
  if (@tag)
   @tag.name = tag.name
   @tag.save
  else
   @tag = Tag.new     
   @tag.name = tag.name      
   @tag.sync_id = tag.id
   @tag.save
  end
 end
end

That bit of code is really bugging me. It is ugly and unweildy.

SOAP:WSDLDriver in Ruby lets you call Web Services and generally it works well. In this case though my Web Service returns an array of Tag which seems to be tripping WSDLDriver up. You create your SOAP object, call the Web Service and then the results are stored in Tag off of the SOAP object.

If there are multiple items then Tag is an array. That is what I expected and it works fine.

However if there is just one item then instead of Tag being an array of one item it is an actual Tag instance. So you have to use different code to access it rather than an array.

It gets worse though. If no items are returned then there is no Tag member at all. The first line of code deals with that. It checks if the SOAP object “responds” to the Tag member. If it does then something was returned but we don’t know yet if it is an array or a single object. So we have to use is_a? Array for that.

With all of this we end up with two blocks of code that really should be one. I can refactor out the add/save/update bit but the nested ifs are ugly.

Ideally the Ruby library should return an array whether or not there are items. I can then simply do a length check on the array.

I may be wrong but this seems a poor design choice on the part of the SOAP:WSDLDriver coder rather than a slight on Ruby itself. Possibly the wonderfully dynamic nature of Ruby has tripped the coder up.

What I am really hoping for is someone to respond to this post and say “Use this line of code instead and you’ll have pretty code again.”

Commenting in Ruby

Tuesday, May 9th, 2006

Oddly I have only just come across this after months of Ruby.

A line comment in Ruby is done using #. e.g.
uncommented_code
# commented code
uncommented_code

Block comments though I had to go look up. Apparently the inventor of Ruby isn’t keen on block comments and so it is done in the following cumbersome manner:
uncommented_code
=begin
commented code
and another line
=end
uncommented_code

Ruby, SOAP and a Date

Tuesday, May 9th, 2006

If you need to send a date parameter to a Web Service using Ruby and SOAP:WSDLDriver then be sure to use the DateTime object. I just spent two mind-numbing hours trying to figure out why it wouldn’t accept my param.

e.g.

dateToUse = DateTime.civil(2005, 1, 1, 1, 1, 1)
soapResponse = soap.GetNewTagsSince(:sinceDate => dateToUse)