Thursday, August 6, 2009

Generator (like an Iterator) in Ruby on Rails

I'm creating a rails-agnostic class in ruby for getting the member photo directory.

Downloading the entire photo directory is slow. It takes a few minutes. Users don't want to wait 3 minutes to find out what is happening (success or failure, etc), but I don't want to put my model code into a library which could otherwise easily be used for non-rails apps.

The main issue here is that once the class instance is gone, so is the authentication. So it doesn't work to just store the URLs to the photos. Each photo must be downloaded. However, if the URLs to the photos are temporarily stored in the class and then downloaded one-by-one in the class, the wait for the text part of the directory to the download is acceptable (for me).

Take a look
http://secure.lds.org/units/login
/Membership Directory/.click
/with photos/i.click

The solution? A generator.
Here's a brief work snippit that shows how my solution works generically:



class Contacts
def import_directory
@records = []
#... get names and photo urls
@records << [:name => 'abc']
@records << [:name => 'jkl']
@records << [:name => 'xyz']
return true
end

def next_contact
if not @gen
create_generator
end
return @gen.next
end

private
def create_generator
require 'generator'
@gen = Generator.new do |g|
for record in @records
g.yield record
end
g.yield nil
end
end
end

contacts = Contacts.new
if not contacts.import_directory
abort 'Invalid Import'
end

while record = contacts.next_contact
puts record
end


I know that generators can be done in python and after a little searching I found this, which inspired me to play around and create an example class solution.
http://anthonylewis.com/2007/11/09/ruby-generators/

No comments:

Post a Comment