Q:

Conjunction and multiple return values

I have validation methods that return a two-element array of true/false and a string. An example is:
def check_length(name)
  if(name.length > 50)
    return false, "Length more than 50"
  else
    return true, ""
  end
end

I'm trying to check for multiple methods of this kind. I wrote a code like the following:
def validate
  value, message =
  check_length(name) &&
  is_valid(id) &&
  is_any_mismatch(name,id) &&
  is_valid(name) &&
  ...
end

I expect value to take the true/false and message the string value. If check_length returns false, the second method is_valid should not be evaluated.
But for the code above, even if check_length returns false, is_valid is evaluated, and value is overridden by the return value of is_valid.
How can we break execution if the first condition is false, and return from validate function? i.e short circuit evaluation should work with two return values.

A:

The return value is an array, so it is never going to be falsy (even if its first element if false). This means that you have to construct the logic the other way using disjunction, not conjunction. A detected error would return an array (i.e., truthy value), and lack of error would be nil. Then finally, you return an array as a default that has true.
def check_length(name)
  if(name.length > 50)
    return false, "Length more than 50"
  else
    return nil
  end
end

def validate
  check_length(name) ||
  is_valid(id) ||
  is_any_mismatch(name,id) ||
  is_valid(name) ||
  ... ||
  [true, ""]
end

This will return a two-element array that has true/false as the first element and the message as the second.

