{"id":1007,"date":"2016-07-10T22:42:27","date_gmt":"2016-07-11T05:42:27","guid":{"rendered":"http:\/\/www.certainly-strange.com\/?p=1007"},"modified":"2016-07-14T22:38:35","modified_gmt":"2016-07-15T05:38:35","slug":"traversing-a-hashiemash","status":"publish","type":"post","link":"http:\/\/www.certainly-strange.com\/?p=1007","title":{"rendered":"Traversing a Hashie::Mash"},"content":{"rendered":"<p>While messing around with gems for Ruby, and in particular Dark Sky&#8217;s weather forecast API, <a href=\"https:\/\/developer.forecast.io\/\">Forecast.io<\/a>, I came across an object type that I hadn&#8217;t used before: the Mash.<\/p>\n<p>It seems like a deeply-nested thing, and I couldn&#8217;t really see an obvious way to iterate over it, so I figured I&#8217;d share the process that I used to unwrap it.<\/p>\n<p>In order to figure out exactly what Forecast.io was returning in the first place, I first used the class method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">forecast = ForecastIO.forecast(latitude, longitude)\r\nputs forecast.class<\/pre>\n<p class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\">which returned:<\/p>\n<blockquote><p>Hashie::Mash<\/p><\/blockquote>\n<p>This is how I figured out it was a Mash in the first place. I then converted the Mash to a hash:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">forecast = forecast.to_hash<\/pre>\n<p>and was then able to see what this resulting hash was composed of, again using the class method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">forecast[\"daily\"].each do |key, value|\r\n\u00a0 puts \"Key name: #{key}\\tKey type: #{key.class}\\tValue type: #{value.class}\"\r\nend<\/pre>\n<p>which returned:<\/p>\n<div><code>Key name: summary Key type: String Value type: String<\/code><\/div>\n<div><code>Key name: icon Key type: String Value type: String<\/code><\/div>\n<div><code>Key name: data Key type: String Value type: Array<\/code><\/div>\n<p>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 &#8220;data.&#8221; &#8220;Summary&#8221; contains today&#8217;s weather summary only, and &#8220;icon&#8221; contains today&#8217;s weather icon only. As we will see, those data are also stored for today&#8217;s date in the forecast, so we don&#8217;t even need to use them for the current day.<\/p>\n<p>But what is each element in this array?<\/p>\n<p>Turns out the data is in an array of 8 hashes &#8211; today&#8217;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&#8217;m interested in is the temperature maximum and minimum, along with the summary.<\/p>\n<pre class=\"prettyprint lang-ruby EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">forecast = ForecastIO.forecast(latitude, longitude)\r\nforecast = forecast.to_hash\r\n\r\nforecast[\"daily\"].each do |key, value|\r\n  if key ==\"data\"\r\n    value.each do |n|\r\n      date = Time.at(n['time'])\r\n      puts \"#{date.month}\/#{date.day}\\nHigh: #{n['temperatureMax']}F\\tLow: #{n['temperatureMin']}F\\n#{n['summary']}\\n--------\"\r\n    end\r\n  end\r\nend<\/pre>\n<p class=\"prettyprint lang-ruby EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">And that successfully pulled everything out and displayed it nice and pretty, so this was one way of traversing the Mash.<\/p>\n<p class=\"prettyprint lang-ruby EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">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:<\/p>\n<pre class=\"prettyprint lang-ruby EnlighterJSRAW\" data-enlighter-language=\"ruby\" data-enlighter-theme=\"twilight\">require 'forecast_io'\r\nrequire 'date'\r\nrequire 'time'\r\nrequire 'geocoder'\r\n\r\ndate = Date.today\r\n\r\nputs \"Enter the city and\/or state you would like to get a forecast for:\"\r\nlocation = gets.chomp\r\nputs \"--------\"\r\n\r\ncity = Geocoder.search(location)\r\nlatitude = city[0].latitude\r\nlongitude = city[0].longitude\r\n\r\nForecastIO.api_key = 'YOUR API KEY'\r\n\r\nforecast = ForecastIO.forecast(latitude, longitude)\r\nforecast = forecast.to_hash\r\n\r\nforecast[\"daily\"].each do |key, value|\r\n\u00a0 if key ==\"data\"\r\n\u00a0 \u00a0 value.each do |n|\r\n\u00a0 \u00a0 \u00a0 date = Time.at(n['time'])\r\n\u00a0 \u00a0 \u00a0 puts \"#{date.month}\/#{date.day}\\nHigh: #{n['temperatureMax']}F\\tLow: #{n['temperatureMin']}F\\n#{n['summary']}\\n--------\"\r\n\u00a0 \u00a0 end\r\n\u00a0 end\r\nend<\/pre>\n<p>For example, if you input &#8220;san francisco,&#8221; you get an output that looks like this:<\/p>\n<div><code>Enter the city and\/or state you would like to get a forecast for:<\/code><\/div>\n<div><code>san francisco<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/11<\/code><\/div>\n<div><code>High: 70.66F Low: 57.11F<\/code><\/div>\n<div><code>Partly cloudy starting in the evening.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/12<\/code><\/div>\n<div><code>High: 69.74F Low: 54.98F<\/code><\/div>\n<div><code>Partly cloudy in the morning.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/13<\/code><\/div>\n<div><code>High: 72.35F Low: 56.02F<\/code><\/div>\n<div><code>Partly cloudy in the morning.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/14<\/code><\/div>\n<div><code>High: 75.86F Low: 55.67F<\/code><\/div>\n<div><code>Partly cloudy in the morning.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/15<\/code><\/div>\n<div><code>High: 75.49F Low: 57.89F<\/code><\/div>\n<div><code>Clear throughout the day.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/16<\/code><\/div>\n<div><code>High: 69.27F Low: 57.4F<\/code><\/div>\n<div><code>Clear throughout the day.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/17<\/code><\/div>\n<div><code>High: 66.31F Low: 56.43F<\/code><\/div>\n<div><code>Mostly cloudy until afternoon.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<div><code>7\/18<\/code><\/div>\n<div><code>High: 66.72F Low: 55.71F<\/code><\/div>\n<div><code>Mostly cloudy until afternoon.<\/code><\/div>\n<div><code>--------<\/code><\/div>\n<p>Hooray!<\/p>\n<p>Although I figure, there&#8217;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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While messing around with gems for Ruby, and in particular Dark Sky&#8217;s weather forecast API, Forecast.io, I came across an object type that I hadn&#8217;t used before: the Mash. It seems like a deeply-nested thing, and I couldn&#8217;t really see an obvious way to iterate over it, so I figured I&#8217;d share the process that &hellip; <a href=\"http:\/\/www.certainly-strange.com\/?p=1007\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Traversing a Hashie::Mash&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[361,362],"tags":[],"class_list":["post-1007","post","type-post","status-publish","format-standard","hentry","category-programming","category-ruby"],"_links":{"self":[{"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=\/wp\/v2\/posts\/1007","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1007"}],"version-history":[{"count":33,"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=\/wp\/v2\/posts\/1007\/revisions"}],"predecessor-version":[{"id":1056,"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=\/wp\/v2\/posts\/1007\/revisions\/1056"}],"wp:attachment":[{"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1007"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1007"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.certainly-strange.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}