class Addressable::URI

def query_values=(new_query_values)

Parameters:
  • new_query_values (Hash, #to_hash, Array) -- The new query values.
def query_values=(new_query_values)
  if new_query_values == nil
    self.query = nil
    return nil
  end
  if !new_query_values.is_a?(Array)
    if !new_query_values.respond_to?(:to_hash)
      raise TypeError,
        "Can't convert #{new_query_values.class} into Hash."
    end
    new_query_values = new_query_values.to_hash
    new_query_values = new_query_values.map do |key, value|
      key = key.to_s if key.kind_of?(Symbol)
      [key, value]
    end
    # Useful default for OAuth and caching.
    # Only to be used for non-Array inputs. Arrays should preserve order.
    new_query_values.sort!
  end
  # new_query_values have form [['key1', 'value1'], ['key2', 'value2']]
  # Algorithm shamelessly stolen from Julien Genestoux, slightly modified
  buffer = ""
  stack = []
  e = lambda do |component|
    component = component.to_s if component.kind_of?(Symbol)
    URI.encode_component(component, CharacterClasses::UNRESERVED)
  end
  new_query_values.each do |key, value|
    if value.kind_of?(Hash)
      stack << [key, value]
    elsif value.kind_of?(Array)
      stack << [
        key,
        value.inject({}) { |accu, x| accu[accu.size.to_s] = x; accu }
      ]
    elsif value == true
      buffer << "#{e.call(key)}&"
    else
      buffer << "#{e.call(key)}=#{e.call(value)}&"
    end
  end
  stack.each do |(parent, hash)|
    (hash.sort_by { |key| key.to_s }).each do |(key, value)|
      if value.kind_of?(Hash)
        stack << ["#{parent}[#{key}]", value]
      elsif value == true
        buffer << "#{parent}[#{e.call(key)}]&"
      else
        buffer << "#{parent}[#{e.call(key)}]=#{e.call(value)}&"
      end
    end
  end
  self.query = buffer.chop
end