How to Use Metaprogramming for Opening and Customizing the String Class in Ruby
In the previous lesson, we went through a basic example of metaprogramming just to get an idea of what it is and how we can use it. In this lesson, let's see a more practical way to use it.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In the previous lesson, we went through a basic example of metaprogramming just to get an idea of what it is and how we can use it. In this lesson, let's see a more practical way to use it.

In this case, we'll open the String class in Ruby. This is a core Ruby class that is used extensively. For example: every time when you declare a variable with a string value you're instantiating an object of the String class.

Now when we define a class called String remember that we're simply reopening this class, we're not creating one from scratch. Let's add a method called censor to block out certain words in an application. Currently, the String class has no such method, so we're not overriding any pre-existing methods. The code will look like this:

class String
  def censor(bad_word)
    self.gsub! "#{bad_word}", "CENSORED"
  end
end

In this code, we are calling self because we want any string to call this method onto itself. We are calling the gsub method and performing some string interpolation that will swap a replacement word instead of the banned word. Essentially, this code will replace the word that gets passed to the censor method with the word CENSORED.

Now, to test it, let's add a sentence that we call the method on:

p "The bunny was in trouble with the king's bunny".censor('bunny')

Running the program will produce this output:

"The CENSORED was in trouble with the king's CENSORED"

Now let's add a new method that gives a new same to a pre-existing piece of functionality. The String class already has a method called size. If we run this method on our string it will produce the following output:

p "The bunny was in trouble with the king's bunny".size # > 46

But what if we want to be able to create a more explicit method name for this feature? We can open up the String class again with this code:

class String
  def num_of_chars
    size
  end
end

If you run this code you'll see that we get the identical output as when we use the size method directly. Now I'll admit this example isn't very practical since the size method is more succinct and works quite well. However it's a feature of Ruby that you may need to use at some point, so it's a good skill to learn.

The nice thing about opening built in classes like the String class is that you're able to add custom behavior that can be called directly on objects such as sentences.