Traversing a Hashie::Mash

While messing around with gems for Ruby, and in particular Dark Sky’s weather forecast API, Forecast.io, I came across an object type that I hadn’t used before: the Mash.

It seems like a deeply-nested thing, and I couldn’t really see an obvious way to iterate over it, so I figured I’d share the process that I used to unwrap it.

In order to figure out exactly what Forecast.io was returning in the first place, I first used the class method:

forecast = ForecastIO.forecast(latitude, longitude)
puts forecast.class

which returned:

Hashie::Mash

This is how I figured out it was a Mash in the first place. I then converted the Mash to a hash:

forecast = forecast.to_hash

and was then able to see what this resulting hash was composed of, again using the class method:

forecast["daily"].each do |key, value|
  puts "Key name: #{key}\tKey type: #{key.class}\tValue type: #{value.class}"
end

which returned:

Key name: summary Key type: String Value type: String
Key name: icon Key type: String Value type: String
Key name: data Key type: String Value type: Array

And so I was able to discover that all the forecast data that I wanted to access was kept in an array, as a value paired to the key called “data.” “Summary” contains today’s weather summary only, and “icon” contains today’s weather icon only. As we will see, those data are also stored for today’s date in the forecast, so we don’t even need to use them for the current day.

But what is each element in this array?

Turns out the data is in an array of 8 hashes – today’s weather plus the seven day forecast. Each hash represents a different day. Each hash contains everything from ozone to pressure to sunset times, and feel free to poke around in there. For now, all I’m interested in is the temperature maximum and minimum, along with the summary.

forecast = ForecastIO.forecast(latitude, longitude)
forecast = forecast.to_hash

forecast["daily"].each do |key, value|
  if key =="data"
    value.each do |n|
      date = Time.at(n['time'])
      puts "#{date.month}/#{date.day}\nHigh: #{n['temperatureMax']}F\tLow: #{n['temperatureMin']}F\n#{n['summary']}\n--------"
    end
  end
end

And that successfully pulled everything out and displayed it nice and pretty, so this was one way of traversing the Mash.

In the end, I was able to make a quick little script to pull out forecast data for a location input by a user using Forecast.io for getting the forecast and geocoder for looking up the latitude/longitude of a location:

require 'forecast_io'
require 'date'
require 'time'
require 'geocoder'

date = Date.today

puts "Enter the city and/or state you would like to get a forecast for:"
location = gets.chomp
puts "--------"

city = Geocoder.search(location)
latitude = city[0].latitude
longitude = city[0].longitude

ForecastIO.api_key = 'YOUR API KEY'

forecast = ForecastIO.forecast(latitude, longitude)
forecast = forecast.to_hash

forecast["daily"].each do |key, value|
  if key =="data"
    value.each do |n|
      date = Time.at(n['time'])
      puts "#{date.month}/#{date.day}\nHigh: #{n['temperatureMax']}F\tLow: #{n['temperatureMin']}F\n#{n['summary']}\n--------"
    end
  end
end

For example, if you input “san francisco,” you get an output that looks like this:

Enter the city and/or state you would like to get a forecast for:
san francisco
--------
7/11
High: 70.66F Low: 57.11F
Partly cloudy starting in the evening.
--------
7/12
High: 69.74F Low: 54.98F
Partly cloudy in the morning.
--------
7/13
High: 72.35F Low: 56.02F
Partly cloudy in the morning.
--------
7/14
High: 75.86F Low: 55.67F
Partly cloudy in the morning.
--------
7/15
High: 75.49F Low: 57.89F
Clear throughout the day.
--------
7/16
High: 69.27F Low: 57.4F
Clear throughout the day.
--------
7/17
High: 66.31F Low: 56.43F
Mostly cloudy until afternoon.
--------
7/18
High: 66.72F Low: 55.71F
Mostly cloudy until afternoon.
--------

Hooray!

Although I figure, there’s got to be a less roundabout-way of getting data out of a Mash (without converting them into hashes), because otherwise why would they even exist? Thus, further research is called for on my part.

Dungeon Keeper II

I’ve started playing Dungeon Keeper II again. I looked into it, and you don’t have to run it on a DOS emulator anymore (yay), because GOG Games apparently buys up old abandonware and keeps it current so it can run on modern systems. I recall that before, even from GOG Games, DKII would crash constantly and was absolutely unplayable. Plus they had a patch to update it to the “latest” version of the game, which also happened to prevent Dark Angels from spawning. Ugh. So I had given up on that for a while.

For whatever reason, I looked into it again this weekend, and found that from GOG Games it is now only $2.39 to buy DKII; plus, I saw in the comments that the game supposedly was updated to run on Windows 7 and Windows 8. At that price, I figured, what the heck. I’ll buy it and see if what they say is true. I wouldn’t mind being out $2.39 if it was still completely unplayable.

So I bought it, and it took a minor bit of tweaking around to get it running on Windows 10 (which nobody claimed it could run on, so this is not surprising), but it wasn’t too bad. Pretty much all I had to do was enable DirectPlay on Windows 10, which you do in Programs and Features by enabling “Legacy Components” in the list of Windows Features to turn on/off, and then enabling “DirectPlay” in the drop-down menu under “Legacy Components.” Et voila!

Dungeon Keeper 2

I got it up and running, and – no crashes! Everything was smooth and perfect. I played it for approximately 1,000,000 hours and it never crashed or lagged once.

But, after approximately 1,000,001 hours of gameplay, I finally discovered that one of the old problems were still there to haunt me. No Dark Angels. Dun-dun-duuuuuhhhnn. Serves me right for doing the campaign first, even though all I wanted to do all along was My Pet Dungeon. If I had started with MPD, I would have noticed this right away.

It didn’t matter if my whole dungeon was nothing but temples, I wouldn’t get a Dark Angel. I might not have noticed, if not for the fact that suddenly a Maiden (dryder) entered my dungeon. I have a deep-seated association with Maidens and the glitches associated with the patch, since they were first introduced in the anti-Angel patch. UGH. I almost quit and stopped playing right then and there. What is there left to aspire to, if you cannot even get Dark Angels?

Fortunately, I did a bit of Googling, and found this site that outlines how to correct the problem caused by the patch, and even provides the necessary files (from the old, non-patched version) to do so. Phew!

As you can see in the above screenshot, after replacing those files, you can now have a dungeon in which Maidens and Dark Angels coexist.

And yes, Warlocks are my favorites forever and ever, which is why I always must have a gillion of them.