I would like to have my method change what it returns depending on how many variables are being assigned by the caller. Is there a way to query this in the method? Or is there a way to encode a 2-value return so that the second value will be ignored if an assignment destination is not supplied? Thanks! --Myles
def foo
if <two-vars-being-assigned>
return [:bar, :baz]
else
return :bar
end
end
x, y = foo
# I want x to get :bar, not [:bar, :baz]
x = foo
If you really wanted to, you could return an object which responds to to_ary. You could even monkey patch Symbol in your example with a to_ary method.
But … NO. Just NO.
class Symbol
def to_ary
[:bar, :baz]
end
end
def foo
:bar
end
a = foo
a #=> :bar
b, c = foo
b #=> :bar
c #=> :baz
Whatever kind of object you return, it will violate the Single Responsibility Principle, since it acts both as whatever the return value is supposed to act as and as a proxy for splitting itself into two return values.
Just … NO. Seriously. NO.
I would agrue that this is not possible. When you call x, y = foo then foo gets evaluated first and therefore runs and returns before the assignment is done. Furthermore, I see no easy and reasonable way to make a method aware of the code structure at the place from which it was called.
Why don't you just handle this at the place in which you call that method:
def foo
[:bar, :baz]
end
x, y = foo
x = foo.first
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With