DEV Community

Cover image for Using the Ruby Percent String Array with #include? for Easy Filtering
Jesse vB
Jesse vB

Posted on

Using the Ruby Percent String Array with #include? for Easy Filtering

What are percent strings?

Ruby is known for providing multiple ways to accomplish the same thing, for instance, creating strings. We can create a new instance of the String class.

string_instance = String.new("largesse")
=> "largesse"
Enter fullscreen mode Exit fullscreen mode

Largesse refers to the act of generously giving money or to the money given. It can also mean "generosity."
-Merriam-Webster.com

Or, more likely, we would use the string literal syntax.

string_literal = "nascent"
=> "nascent"
Enter fullscreen mode Exit fullscreen mode

Nascent means "coming or having recently come into existence."
-Merriam-Webster.com

They are both instances of the String class.

string_instance.is_a? String
=> true
string_literal.class
=> String
Enter fullscreen mode Exit fullscreen mode

There's another way...
Do you know about Ruby "Percent Strings"? As the name implies, they use a percent sign.

percent_string = %(elucidate)
=> "elucidate"
Enter fullscreen mode Exit fullscreen mode

Elucidate means "to make something that is hard to understand clear or easy to understand.
-Mirriam-Webster.com

Cool! But why would we need this? Hopefully I can elucidate with a practical example. Even if your Ruby skills are in nascent state, you can still take full advantage of the various ways to make Strings. Thanks, Ruby, for your largesse in this area.


The percent operator in Ruby has several uses. Here's one I find helpful: %w[].

Typing a long list of strings into an array can be tedious because of all the quotation marks and commas. We don't have to type them! Let's let Ruby do it for us, using the percent string array notation.

cool_words = %w[nascent largesse elucidate]
=> ["nascent", "largesse", "elucidate"]
Enter fullscreen mode Exit fullscreen mode

I don't know what "w" stands for. If you do, maybe you can leave a comment. I consider it to mean "words". That's how I remember it. Here's a few more.

%s[checkout these symbols]
=> [:checkout, :these, :symbols]
Enter fullscreen mode Exit fullscreen mode

Using %W with an uppercase 'W' allows for interpolation.

my_favorite_color = "teal"
cool_colors = %W[lapis\ lazuli smaragdine mikado xanadu #{my_favorite_color}]
=> ["lapis lazuli", "smaragdine", "mikado", "xanadu", "teal"]
Enter fullscreen mode Exit fullscreen mode

A Practical Example with the #include? Method

This is really helpful.

You have a collection of objects that you want to filter based on data in the form a string. Checkout this array of accounts.

# lot's of them!
accounts.size
=> 36671

# they have a status attribute
accounts.first.status
=> 'Disabled'

accounts.last.status
=> 'Canceled'

accounts[2838].status
=> 'Active'
Enter fullscreen mode Exit fullscreen mode

Now, you need to add a Boolean attribute to the Account class called @do_not_display that depends on the status. Since you want to set this dynamically, you add a private method to your class called get_do_not_display which checks the status and returns true if the account matches a list of statuses.

# hmm... how should we do this?
# Oh! I know!
class Account
  attr_accessor :status, :do_not_display
  def initialize status
    @status = status
    @do_not_display = get_do_not_display
  end 

  private

  def get_do_not_display
    return true if @status == "Disabled" || "Canceled"
    false
  end
end
Enter fullscreen mode Exit fullscreen mode

That works, but what if your list of strings to filter by is growing and changing based on the needs of the application? Here's a better way that uses the percent string array.

def get_do_not_display
  return true if %w[DISABLED CANCELED FORGOTTEN ABANDONED DESTROYED BROKEN HACKED DELINQUENT OTHER].include? @status.upcase.strip
  return false
end
Enter fullscreen mode Exit fullscreen mode

Finally, here's how you might use this attribute in your template.

#accounts.html.erb
<ul>
  <% Account.each do |account| %>
    <li>
      <%= account.id unless account.do_not_display %>
    </li>
  <% end %>
</ul>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)