For a school project I was told to build a Ruby gem that you could interact with through the CLI. Here’s the process I went through:

1 —General Outline

I decided I wanted it to involve sports, and at first decided that I would scrape the MLB games from ESPN and build a gem that allowed you to look at today’s games, and would allow you to see more details regarding each game. But after attempting to scrape the data on my own and then later with help from a much better programmer, we found that ESPN doesn’t really like scrapers and/or loads their scores as to make scraping very difficult. So I scraped that idea.

Yes, that was intentional.

I ended up deciding to scrape the teams that have been enshrined in the NBA Hall of Fame. Why? Because -

A. I like basketball more than baseball anyway, 🏀

B. I feel like there’s a lot of interesting history behind these teams that even the most devoted fan wouldn’t know,

C. Because it was a lot more static than ESPN and I could get it to work.

So my gem would show you all the teams in the Hall of Fame, and then my typing a number you could see more about each team.

2 — Gem Structure

Now that I had an idea, it was time to create an outline of the classes and their purpose. For this project that wasn’t going to be too difficult. Obviously we needed to scrape the data, and then organize that data, and finally display the data and allow people to interact with it. So my first class I called Scraper. Its purpose was to scrape the HOF page and return a list of the teams. Here’s the page I scraped from:

The only data I could scrape from this page is the name of the team and the url for each teams page. I would have to go into each team page to grab the other pieces of information I wanted on the team, such as the description, enshrinement date, and facts about the team. I didn’t want the Scraper class to do that though, I wanted each team to be an instance of a Team class that would be in charge of grabbing the info themselves. I wanted each team to take ownership of its data, in other words. If the info in the Team class was wrong, I wanted it to be because of a mistake in the Team class.

Finally, I would need to create a CLI class that would take the info from the Team class and display it so that the user could interact with it.

3 — Building the Gem 💎

Now that I knew what I wanted, it was time to actually build the sucker. There was a clear build order here — Scraper class to grab the data and create the teams, Team class to grab additional info about itself from its url, and a CLI class to display to info and to interact with the user. The scraper was the easiest class to build, I just needed to install and iterate through the page, creating a new instance of the team class and giving it its name and url so it could do the rest itself. Each Team class instance would then go into its url and grab the description about the team and other pieces of data about itself.

Here I ran into a few silly problems that took me longer than they should have to figure out. My team class instance was great at being initialized with a name and url, but wouldn’t receive the scraped data I assigned it. If I pryed into it and then called on the description method, for example I would get a NilClass error. It was supposed to take the document from the doc method and grab the info using the CSS selectors I had given it. I had a doc method that returned the team’s webpage organized using Nokogiri. Why wouldn’t it work? I noticed that I would first have to call on the team.doc method to avoid the NilClass error and it would work fine after that. After a lot of fiddling I saw the reason — I had been assigning all these methods using @doc instead of calling the doc method that returned it. 🤦‍♂ Since @doc wasn’t assigned at initialization, there wasn’t anything for the other methods to sift through. Easy fix though. I found another issue while working on the CLI — for some teams the team.description method wasn’t grabbing anything. Darn website. After looking at the website again, I changed the css selectors to be more general to make up for their lack of uniformity, which thankfully wasn’t as hard as it could have been. The hardest part of each team’s webpage to scrape was the facts. They weren’t organized very well and I used Regex, which is a pain, btw, to grab and organize the info in a displayable way. Here’s my end result:

doc.css(“div.stat-item”)[i].to_s.gsub(/<(.*?[^>])>/){|s| s = “ “}.strip.gsub(“\n\t”, “-”)

If it looks hard, that’s because it was. And if it doesn’t, go bug someone else.

The CLI class was next. I needed a method to display all the teams and the beginning, and then each team as users asked for more info about them. Then I needed a method that ran though the program and accepted user inputs and all that. Add in a good readme file and boom. There you go.

If you’re interested in seeing the results click .

Thanks for reading.