From 8cc460f94e31b23c91075e0c3cc4511f510ff03f Mon Sep 17 00:00:00 2001 From: Alex Reisner <alex@alexreisner.com> Date: Sat, 5 Mar 2011 17:50:29 -0500 Subject: [PATCH] Make lookups return a single result (no array). More than one result is very rare and it's not clear how one would evaluate the choices. If this is required in the future a new method can be added. --- lib/geocoder.rb | 10 +++++----- lib/geocoder/lookups/base.rb | 13 ++++++------- lib/geocoder/lookups/freegeoip.rb | 4 ++-- lib/geocoder/lookups/google.rb | 4 ++-- lib/geocoder/lookups/yahoo.rb | 4 ++-- lib/geocoder/orms/base.rb | 2 +- lib/geocoder/results/base.rb | 14 ++++++++++++++ test/geocoder_test.rb | 26 +++++++++++++------------- 8 files changed, 45 insertions(+), 32 deletions(-) diff --git a/lib/geocoder.rb b/lib/geocoder.rb index b9e9c704..4deeeea5 100644 --- a/lib/geocoder.rb +++ b/lib/geocoder.rb @@ -10,7 +10,7 @@ module Geocoder # Search for information about an address or a set of coordinates. # def search(*args) - return [] if blank_query?(args[0]) + return nil if blank_query?(args[0]) ip = (args.size == 1 and ip_address?(args.first)) lookup(ip).search(*args) end @@ -19,8 +19,8 @@ module Geocoder # Look up the coordinates of the given street or IP address. # def coordinates(address) - if (results = search(address)).size > 0 - results.first.coordinates + if result = search(address) + result.coordinates end end @@ -28,8 +28,8 @@ module Geocoder # Look up the address of the given coordinates. # def address(latitude, longitude) - if (results = search(latitude, longitude)).size > 0 - results.first.address + if result = search(latitude, longitude) + result.address end end diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index 92884cc9..c07080f5 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -12,17 +12,16 @@ module Geocoder class Base ## - # An array of Geocoder::Result objects. + # Query the geocoding API and return a Geocoder::Result object. + # Returns +nil+ on timeout or error. # # Takes a search string (eg: "Mississippi Coast Coliseumf, Biloxi, MS", # "205.128.54.202") for geocoding, or coordinates (latitude, longitude) # for reverse geocoding. # def search(*args) - if res = results(args.join(","), args.size == 2) - res.map{ |r| result_class.new(r) } - else - [] + if res = result(args.join(","), args.size == 2) + result_class.new(res) end end @@ -30,9 +29,9 @@ module Geocoder private # ------------------------------------------------------------- ## - # Array of results, or nil on timeout or other error. + # Geocoder::Result object or nil on timeout or other error. # - def results(query, reverse = false) + def result(query, reverse = false) fail end diff --git a/lib/geocoder/lookups/freegeoip.rb b/lib/geocoder/lookups/freegeoip.rb index ee6d8a69..791bac4c 100644 --- a/lib/geocoder/lookups/freegeoip.rb +++ b/lib/geocoder/lookups/freegeoip.rb @@ -6,10 +6,10 @@ module Geocoder::Lookup private # --------------------------------------------------------------- - def results(query, reverse = false) + def result(query, reverse = false) begin if doc = fetch_data(query, reverse) - [doc] + doc end rescue StandardError # Freegeoip.net returns HTML on bad request nil diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb index 52f87238..ed263c97 100644 --- a/lib/geocoder/lookups/google.rb +++ b/lib/geocoder/lookups/google.rb @@ -6,10 +6,10 @@ module Geocoder::Lookup private # --------------------------------------------------------------- - def results(query, reverse = false) + def result(query, reverse = false) doc = fetch_data(query, reverse) case doc['status']; when "OK" - doc['results'] + doc['results'].first when "OVER_QUERY_LIMIT" warn "Google Geocoding API error: over query limit." when "REQUEST_DENIED" diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb index efab5c84..e8665fa0 100644 --- a/lib/geocoder/lookups/yahoo.rb +++ b/lib/geocoder/lookups/yahoo.rb @@ -6,10 +6,10 @@ module Geocoder::Lookup private # --------------------------------------------------------------- - def results(query, reverse = false) + def result(query, reverse = false) doc = fetch_data(query, reverse) if doc = doc['ResultSet'] and doc['Error'] == 0 - doc['Results'] + doc['Results'].first else warn "Yahoo Geocoding API error: #{doc['Error']} (#{doc['ErrorMessage']})." end diff --git a/lib/geocoder/orms/base.rb b/lib/geocoder/orms/base.rb index dedeefe4..422a9b37 100644 --- a/lib/geocoder/orms/base.rb +++ b/lib/geocoder/orms/base.rb @@ -50,7 +50,7 @@ module Geocoder args.map!{ |a| send(options[a]) } # passing a block to this method overrides the one given in the model - if result = Geocoder.search(*args).first + if result = Geocoder.search(*args) if block_given? yield(self, result) else diff --git a/lib/geocoder/results/base.rb b/lib/geocoder/results/base.rb index 10844002..b24a0193 100644 --- a/lib/geocoder/results/base.rb +++ b/lib/geocoder/results/base.rb @@ -39,6 +39,20 @@ module Geocoder def country_code fail end + + def [](i) + if i == 0 + warn "DEPRECATION WARNING: You called '[0]' on a Geocoder::Result object. Geocoder.search(...) now returns a single result instead of an array so this is no longer necessary. This warning will be removed and an error will result in geocoder 1.0." + elsif i.is_a?(Fixnum) + warn "DEPRECATION WARNING: You tried to access a Geocoder result but Geocoder.search(...) now returns a single result instead of an array. This warning will be removed and an error will result in geocoder 1.0." + end + self + end + + def first + warn "DEPRECATION WARNING: You called '.first' on a Geocoder::Result object. Geocoder.search(...) now returns a single result instead of an array so this is no longer necessary. This warning will be removed and an error will result in geocoder 1.0." + self + end end end end diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb index 0915e94e..34fa5c4c 100644 --- a/test/geocoder_test.rb +++ b/test/geocoder_test.rb @@ -61,13 +61,13 @@ class GeocoderTest < Test::Unit::TestCase # --- Google --- def test_result_address_components_of_type - results = Geocoder.search("Madison Square Garden, New York, NY") + result = Geocoder.search("Madison Square Garden, New York, NY") assert_equal "Manhattan", - results.first.address_components_of_type(:sublocality).first['long_name'] + result.address_components_of_type(:sublocality).first['long_name'] end def test_google_result_has_required_attributes - result = Geocoder.search("Madison Square Garden, New York, NY").first + result = Geocoder.search("Madison Square Garden, New York, NY") assert_result_has_required_attributes(result) end @@ -76,20 +76,20 @@ class GeocoderTest < Test::Unit::TestCase def test_yahoo_result_components Geocoder::Configuration.lookup = :yahoo - results = Geocoder.search("Madison Square Garden, New York, NY") - assert_equal "10001", results.first.postal + result = Geocoder.search("Madison Square Garden, New York, NY") + assert_equal "10001", result.postal end def test_yahoo_address_formatting Geocoder::Configuration.lookup = :yahoo - results = Geocoder.search("Madison Square Garden, New York, NY") + result = Geocoder.search("Madison Square Garden, New York, NY") assert_equal "Madison Square Garden, New York, NY 10001, United States", - results.first.address + result.address end def test_yahoo_result_has_required_attributes Geocoder::Configuration.lookup = :yahoo - result = Geocoder.search("Madison Square Garden, New York, NY").first + result = Geocoder.search("Madison Square Garden, New York, NY") assert_result_has_required_attributes(result) end @@ -97,17 +97,17 @@ class GeocoderTest < Test::Unit::TestCase # --- FreeGeoIp --- def test_freegeoip_result_on_ip_address_search - results = Geocoder.search("74.200.247.59") - assert results.first.is_a?(Geocoder::Result::Freegeoip) + result = Geocoder.search("74.200.247.59") + assert result.is_a?(Geocoder::Result::Freegeoip) end def test_freegeoip_result_components - results = Geocoder.search("74.200.247.59") - assert_equal "Plano, TX 75093, United States", results.first.address + result = Geocoder.search("74.200.247.59") + assert_equal "Plano, TX 75093, United States", result.address end def test_freegeoip_result_has_required_attributes - result = Geocoder.search("74.200.247.59").first + result = Geocoder.search("74.200.247.59") assert_result_has_required_attributes(result) end -- GitLab