tim_xyz tim_xyz - 1 year ago 83
Ruby Question

Construct a Ruby array with conditional logic inside

How can you construct an array in Ruby which only uses a variable if it exists, and otherwise uses

in its place. With the conditional logic inside the array constructor.

Simplified Example:

a = 1
c = 3

arr = [a, b || nil, c]

I've tried a number of different way but they are not working so I feel like I'm missing something fundamental here.

  1. (b || nil)

  2. b ? b : nil

  3. b.nil? ? nil : b

Is this possible?

This array constructor is used inside a loop used by multiple different models. Some models have the
attribute and some do not, making it difficult extrapolate the logic outside.

Answer Source

Given that your b is actually a model attribute which may or may not be supported by the current self, then b is not a variable at all, b is a method call and you're not interested in whether or not the "variable" exists, you're interested in whether or not self responds to b. Hence you want to use respond_to?:

arr = [a, respond_to?(:b) ? b : nil, c]

or perhaps:

arr = [a, respond_to?(:b, true) ? b : nil, c]

if you want to allow b to be a non-public method.

defined?(b) should also work in this case (unless b's accessor method is automatically created via method_missing) but it will be rather puzzling to anyone looking at your code. Using respond_to? to see if an object has a method/attribute would be more idiomatic.

Using respond_to? when faced with method_missing of course assumes that both method_missing and respond_to? have been overridden but that should be a relatively safe assumption.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download