I was wondering if anyone could point out a cleaner better way to write my code which is pasted here. The code scrapes some data from yelp and processes it into a json format. The reason I’m not using hash.to_json is because it throws some sort of stack error which I can only assume is due to the hash being too large (It’s not particularly large).
- Response object = a hash
- text = the output which saves to file
Anyways guidance appreciated.
def mineLocation
client = Yelp::Client.new
request = Yelp::Review::Request::GeoPoint.new(:latitude=>13.3125,:longitude => -6.2468,:yws_id => 'nicetry')
response = client.search(request)
response['businesses'].length.times do |businessEntry|
text =""
response['businesses'][businessEntry].each { |key, value|
if value.class == Array
value.length.times { |arrayEntry|
text+= "\"#{key}\":["
value[arrayEntry].each { |arrayKey,arrayValue|
text+= "{\"#{arrayKey}\":\"#{arrayValue}\"},"
}
text+="]"
}
else
text+="\"#{arrayKey}\":\"#{arrayValue}\","
end
}
end
end
It looks like all your code is ultimately doing is this:
Which works just fine for me.
If, for whatever reason you really must write your own implementation of a JSON emitter, here’s a couple of tips for you.
The number 1 thing you completely ignore in your code is that Ruby is an object-oriented language, more specifically a class-based object-oriented language. This means that problems are solved by constructing a network of objects that communicate with each other via message passing and respond to those messages by executing methods defined in classes to which those objects belong.
This gives us a lot of power: dynamic dispatch, polymorphism, encapsulation and a ton of others. Leveraging those, your JSON emitter would look something like this:
mine_locationlooks just like above, except obviously without therequire 'json'part.If you want your JSON nicely formatted, you could try something like this:
There’s actually nothing Ruby-specific in this code. This is pretty much exactly what the solution would look like in any other class-based object-oriented language like Java, for example. It’s just object-oriented design 101.
The only thing which is language-specific is how to “modify” classes and add methods to them. In Ruby or Python, you literally just modify the class. In C# and Visual Basic.NET, you would probably use extension methods, in Scala you would use implicit conversions and in Java maybe the Decorator Design Pattern.
Another huge problem with your code is that you are trying to solve a problem which is obviously recursive without actually ever recursing. This just can’t work. The code you wrote is basically Fortran-57 code: procedural with no objects and no recursion. Even just moving one step up from Fortran to, say, Pascal, gives you a nice recursive procedural solution:
Of course, you can play the same game with indentations here:
Here’s the indented output of
puts mine_location, produced using either the second (indented) version ofto_jsonor the second version ofjsonify, it doesn’t really matter, they both have the same output: