The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Ruby code, up for some (Hopefully.) constructive criticizm.

In an attempt to learn more about Ruby I've decided to create a feed reader. Nothing terribly complex yet, the code and an example of it's usage (Lines 28 through 45.) can be seen here:

A bit of an overview along with my thought process:

Line 2 - Shortcut accessor, example usage on line 40.Line 6 - Even though there are modules for RSS versions 0.9 and 1.0, the module for version 2.0 appears to be reverse compatible.Lines 11 and 12. - Inbound assignment along with a little bit of regex trickery to remove an leading "http://". Makes me question the proper use of instance variables.Line 18 - An early attempt at error handling, it took quite a bit of digging to find the get_response function. Lines 21 through 23. - Add the entries.

A live example of the output can be found here. There are no comments yet, as the more that I read into this the more often things change. I've also got to figure out how to escape the entities in the 6th group on the 5th entry so that they can resemble what's used in the feed. Just an attempt at learning Ruby and an early iteration, thanks alot for any insight, it's appreciated.

line 1: open-uri is a standard Ruby library that lets you open a document on the web with the function open(url). This way you don't have to do magic with regexes to get the right format for the url (open can figure everything out).

line 4: I used a function instead of a class because it is very simple, and a class with one menthod doesn't make sense. You can always wrap it in a class if you need more functionality. But I prefer an approach that uses functions because it is often simpler. I also gave total_entries a default value, so we can omit it in most calls.

line 5: Here you see the call to open. It also uses a block which will be called with the downloaded result.

line 6: Parse the feed and extract the channel

line 7: the items[0...total_entries] removes all entries beyond total_entries. I used three dots because we want 5 entries. If there were 2 dots, Ruby would extract the first 6 entries.

line 8 + 9: If you ever want to take an array, do something with the items in it, and put the result in an array, map is your friend, because it does it for you. It "maps" all items to item.title.strip, and returns the result (so it does not modify the original, if you want that, use map!). Note that we don't need an explicit return statement, because the last thing in a function will be returned automatically.

line 14..16: I use literal notation for arrays. It is more convenient than foo = Array.new; foo[0] = ...; foo[1] = ...;

line 18..23: Nothing special here.

line 25: if you call puts without arguments, it prints a newline. (so you don't need "\n")
If you have any questions, please ask!

Wow, thanks for the response. I was actually using OpenURI at first, but there were two problems:

1) The project is hosted on my personal website, which doesn't have the OpenURI module installed. I realize it's not big deal as I can just load it with a relative path, it's just an annoyance.

2) When a website is down it responds with a fatal error. I read through the section on error handling in the second edition of Programming Ruby, nothing worked as I would like. So I used the Net/HTTP module on line 18 to check for a successful connection.

I'm definitely going to have to check out everything else, thanks so much for the response, I appreciate it. On another note, was my use of instance variables accurate? I figure if I use them on inbound (Variables being assigned from parameters.) and outbound (Variables that I would typically use accessor methods for.) I would be good to go. Thanks again!

Edit: I've cleaned things up a bit:

9 lines shorter and much clearer, though I'm still not sure if I'm using instance variables as intended. Anyways, thanks again, I appreciate it.

for x in y delegates to obj#each. That means that you can use for x in y on every object that supports #each. I find the for loop easier to read (just taste).

@poster: your use of instance variables is accurate, but you could use an Entry class, instead of an array of entry titles (that would be more oo, and more extensible if you want to read the content of each post too.

for x in y delegates to obj#each. That means that you can use for x in y on every object that supports #each. I find the for loop easier to read (just taste).

True, the result is the same. But getting used to each, as opposed to for x in y, makes each_with_index, map, and inject, feel a little easier, and look more natural in your code. The ruby mailing list tends to consider the each syntax the "more standard" method, but of course, to each his own