Using the Ruby Percent String Array with #include? for Easy Filtering
Tags: ruby
Published: 2022-03-27 00:34:13

## 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.

```ruby
string_instance = String.new("largesse")
=> "largesse"
```
> 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.
```ruby
string_literal = "nascent"
=> "nascent"
```
> Nascent means "coming or having recently come into existence." 
> -Merriam-Webster.com

They are both instances of the String class.
```ruby
string_instance.is_a? String
=> true
string_literal.class
=> String
```
There's another way...
Do you know about Ruby "Percent Strings"? As the name implies, they use a percent sign.
```ruby
percent_string = %(elucidate)
=> "elucidate"
```
> 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.
```ruby
cool_words = %w[nascent largesse elucidate]
=> ["nascent", "largesse", "elucidate"]
```
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.
```ruby
%s[checkout these symbols]
=> [:checkout, :these, :symbols]
```
Using `%W` with an uppercase 'W' allows for interpolation.
```ruby
my_favorite_color = "teal"
cool_colors = %W[lapis\ lazuli smaragdine mikado xanadu #{my_favorite_color}]
=> ["lapis lazuli", "smaragdine", "mikado", "xanadu", "teal"]
```
---
## 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.

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

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

accounts.last.status
=> 'Canceled'

accounts[2838].status
=> 'Active'
```
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.

```ruby
# 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
```
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.

```ruby
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
```

Finally, here's how you might use this attribute in your template.
```ruby
#accounts.html.erb
<ul>
  <% Account.each do |account| %>
    <li>
      <%= account.id unless account.do_not_display %>
    </li>
  <% end %>
</ul>
```