Question

Is it possible to return multiple values from a function?

I want to pass the return values into another function, and I wonder if I can avoid having to explode the array into multiple values

My problem? I am upgrading Capybara for my project, and I realized, thanks to CSS 'contains' selector & upgrade of Capybara, that the statement below will no longer work

has_selector?(:css, "#rightCol:contains(\"#{page_name}\")")

I want to get it working with minimum effort (there are a lot of such cases), So I came up with the idea of using Nokogiri to convert the css to xpath. I wanted to write it so that the above function can become

has_selector? xpath(:css, "#rightCol:contains(\"#{page_name}\")")

But since xpath has to return an array, I need to actually write this

has_selector?(*xpath(:css, "#rightCol:contains(\"#{page_name}\")"))

Is there a way to get the former behavior?

It can be assumed that right now xpath func is like the below, for brevity.

def xpath(*a)
  [1, 2]
end
Was it helpful?

Solution

You cannot let a method return multiple values. In order to do what you want, you have to change has_selector?, maybe something like this:

alias old_has_selector? :has_selector?
def has_selector? arg
  case arg
  when Array then old_has_selector?(*arg)
  else old_has_selector?(arg)
  end
end

OTHER TIPS

Ruby has limited support for returning multiple values from a function. In particular a returned Array will get "destructured" when assigning to multiple variables:

def foo
  [1, 2]
end

a, b = foo
a #=> 1
b #=> 2   

However in your case you need the splat (*) to make it clear you're not just passing the array as the first argument.

If you want a cleaner syntax, why not just write your own wrapper:

def has_xpath?(xp)
  has_selector?(*xpath(:css, xp))
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top