How to return more than one value at a time from Ruby method?

In Ruby the result of method last evaluated expression becomes a method return value. But what if more than one value needs to be returned? Well, we can do something like this:

def affection
  return "I love", "Ruby"
end

which returns an array of 2 elements. We can also return 3 or more values separating them by comma.

 

It is fine in simple cases, but if both values are related, as in the example below (response object and request url respectively)

def get_content
  url = "http://www.perfectionlabs.com/quicks/qs"
  res = ... #Net:HTTPResponse object
  return res, url
end

it is considered bad approach to return them as an array – it is not how the object programming should look like. We can return a hash, but again it still looks bad as (oversimplifying) hash is an array with key-value pairs. Here’s what can be done – extend runtime objects at runtime to bind related values together. For example:

require “net/http”
require “uri”

module UrlAware
  attr_accessor :url
end

def get_response
  url = URI.parse(“http://www.perfectionlabs.com/”)
  Net::HTTP.start(url.host, url.port) do |http|
    res = http.request(Net::HTTP::Get.new(“/quicks/qs”))
    res.extend UrlAware
    res.url = url
    res
  end 
end

p get_response

The standard Ruby Net::HTTPResponse object does not provide request source url, but it can be easily added by extending res object on runtime with UrlAware module. This method is perfectly safe as only the res object gets extended not the whole Net::HTTPResponse class.

Leave a Reply