0

I'm trying to do some calculations and get the groups and departments array from there. but if I'm returning it like this [], [] It is giving error, while if I return it like [[],[]] it is working fine but in the later case, 3 arrays will get initialize which I want to avoid? Is there any better way to do it using 2 array itself?

    def fetch_group_dept_values
      if condition
        [1,2,3,], [4,5]
      else  
        [9,15], [10,11]
      end
    end

    groups, departments = fetch_group_dept_values 

4
  • In the case you must return Array of Arrays. Commented Apr 17, 2020 at 10:36
  • I wanted to avoid that as it will initialize 3 arrays instead of 2? Commented Apr 17, 2020 at 10:44
  • The issue is resolved, if I use return in front then it is possible to do so, my mentor @Amala_Ray have suggested it. Commented Apr 17, 2020 at 10:55
  • 1
    According to the Ruby Language Specification, return multiple values is done by allocation an array, so there is no difference semantically. Pragmatically, there is also no difference, because an optimizing compiler like TruffleRuby will optimize the array away in both cases. So, semantically, there will always be 3 arrays, whereas pragmatically, depending on your Ruby implementation, there will always be 2. Commented Apr 17, 2020 at 11:14

2 Answers 2

3

if I return it like [[],[]] it is working fine but in the later case, 3 arrays will get initialize which I want to avoid?

It cannot be avoided because a method can only return a single object.

So wrapping the objects in [...] is just fine:

def fetch_group_dept_values
  if condition
    [[1, 2, 3,], [4, 5]]
  else  
    [[9, 15], [10, 11]]
  end
end

The overhead of creating a (small) extra array is negligible.

However, you could avoid the outer array by yielding the values instead of returning them:

def fetch_group_dept_values
  if condition
    yield [1, 2, 3,], [4, 5]
  else  
    yield [9, 15], [10, 11]
  end
end

And call it via:

fetch_group_dept_values do |groups, departments|
  # ...
end
Sign up to request clarification or add additional context in comments.

5 Comments

But you can write an explicit return with a list of multiple values, which is however exactly the same as returning an Array. E.g. def foo; return 1, 2, 3, end is exactly the same as def foo; [1, 2, 3] end.
@JörgWMittag yield a, b, c is not the same as yield [a, b, c] – see the example for next_values.
Oh, whow, I never noticed this asymmetry. Indeed, return, break, and next all work the same (In the ISO Ruby Language Specification, break and next literally just refer to return) but yield works different. Well, well, well, one never ceases to learn.
I would like to add that yielding is most likely not worth the hassle. Creating an array with two references to two other arrays doesn't take up much resources. Such an optimisation can be made. If OP is worried about system resources I'm sure OP can find better things to optimize in their program.
An alternative to yield is to return an enumerator that generates arrays (e.g., [1,2,3] and [4,5]).
1

Use return in front,

   def fetch_group_dept_values
      if condition
        return [1,2,3,], [4,5]
      else  
        return [9,15], [10,11]
      end
    end

    groups, departments = fetch_group_dept_values 

1 Comment

Note that this wraps the return values in an array anyway, because return a, b is defined to be the same as return [a, b]. A Sufficiently Smart Compiler™ may optimize the array away for cases like def foo; return 1, 2 end; a, b = foo, but then it will also optimize away def foo; [1, 2] end; a, b = foo in the same way, so there is no difference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.