DEV Community

A trick with Ruby array literals

Fran C. on February 10, 2020

Declaring an array in Ruby is simple: ary = ["foo", "bar"] # => ["foo", "bar"] Enter fullscreen mode Exit fullscreen mode ...
Collapse
 
thepeoplesbourgeois profile image
Josh • Edited

Good information and well-written! At one of my companies, I picked up the pattern of making a class for constants within their namespace, and referring to the array of them as ALL. Example:

class BikeShed
  module Colors
    ALL = [
      RED = 'red',
      BLUE = 'blue',
      # ...
    ]
  end

  # ...
end

This was especially helpful as more and more categories of constants became part of the codebase

Collapse
 
nflamel profile image
Fran C.

Never thought about using a separate module to keep them grouped but it is a really good technique.

I topically use this in a way in which the constants end up being almost private.
I either wrap the value checks in small predicate methods:

def red?
  color == COLORS_RED
end

Or if I need them with active record I create scopes like the ones in the post.

Even in tests I try to avoid using them for setup and if I have factory_bot at hand I create traits for the different values instead.

This way you end up with code which is a bit more decoupled from this specific implementation detail and when your constant is not enough and you need to build an object instead you'll save a lot of grepping and seddingπŸ˜…

Collapse
 
philnash profile image
Phil Nash

There's some good enum style tricks on this page! Thanks to both of you for sharing.

Collapse
 
nflamel profile image
Fran C.

Thanks to you for reading!

Collapse
 
rhymes profile image
rhymes

Interesting trick to create enums values on the fly, though I guess those are variables not constants, but maybe one can sneak a .freeze inline πŸ˜‚

Collapse
 
nflamel profile image
Fran C.

Sure! Nothing is really constant in Ruby... you can even use symbols if they fit your need.

Collapse
 
bizzibody profile image
Ian bradbury

I do this...

if user = User.find(params[:id])
puts "User is #{user.name}"
end

All the time!

Does this make me a bad person?

Collapse
 
nflamel profile image
Fran C.

xD not at all.

The reason why I prefer to keep declaration and conditionals separated is because it helps a bit with reading the code and I've found more than once that it is not always understood!

I've seen teammates trying to "fix" it as if user == User.find(params[:id]) because they weren't understanding I was just assigning something! Besides, Ruby emits a warning in this case... so it is not clear at all even when you can do it.

The difference with the case of the constants is that the constants declaration doesn't usually involve your applications's logic, so it is easier to reason about and less "dangerous".