'Using operators, how to set a variable equal to one of two other variables depending on which one has a value, in Ruby? [closed]

When there are only two states for instance variable "a", either it has a value or not, and there is only one possible state for instance variable "b", it has a value. I can set "a" equal to "b" if "a" does not have a value via:

@a = nil
@b = "world"

def set_a
    @a ||= @b
end

set_a

p @a
 => "world"
@a = "hello"
@b = "world"

def set_a
    @a ||= @b
end

set_a

p @a
 => "hello"

But, what if there is more than one option for "a" to be set to? For example, I want to set instance variable "a" to either "b" or "c" depending on which has a value. In the program, only either "b" or "c" will have a value, always one but never both. Is there a way, using operators to write something like the following:

if @a == nil
   if @b == nil
      @a = @c
   else
      @a = @b
   end
end

I was trying to write something that looks like this:

def set_a
    @a ||= (@b || @c)
end

But, if @a had a value it would remain. Which is what I want. However, if @a was nil, then it would not take on the value of either @b or @c, it would remain nil.

Thank you for you time.



Solution 1:[1]

You can write

Module.const_defined?(:A) ? A : (B == true ? B : C)

to obtain the value of A.

A not defined
B = true
Module.const_defined?(:A) ? A : (B == true ? B : C)
  #=> true
A not defined
B = false
Module.const_defined?(:A) ? A : (B == true ? B : C)
  #=> 42
A = "cat"
B = false
C = 42
Module.const_defined?(:A) ? A : (B == true ? B : C)
  #=> "cat"

See Module#const_defined?.

Solution 2:[2]

Constants and local variables will raise NameError if not defined. You probably want to use instance variables instead, as they are auto-vivified as nil when referenced even if they haven't been assigned to yet. For example:

@a ||= (@b || @c)
#=> nil

If either @a or @b are truthy, then things will probably work as you expect. However, if all three variables are falsey, then @a will be assigned the value of @c even if @c evaluates as nil or false.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Todd A. Jacobs