Image for post
Image for post
Source: unsplash.com

The defined? keyword in Ruby

An overview of the defined? keyword with a use case from the Ruby source code.. and an optimization tip!

Mehdi Farsi
Sep 17 · 3 min read

In this article, we’re going to explore the following topics:

  • the defined? keyword
  • defined? in the context of resolv-replace
  • defined? yield vs block_given?

I’m thrilled to share with you our latest project: Fun Facts about Ruby — Volume 1

Please feel free to spread the word and share this link! 🙏

Thank you for your time!

The defined? keyword

In Ruby, the defined? keyword returns a string that represents the type of the entity passed as argument. Here is an exhaustive list of what you can pass to defined?

Here, we can see that defined? handles a maximum of cases. But some cases are more relevant than others. For example, let’s see how the resolv-replace library — available in the Ruby Standard Library — takes advantage of this keyword to handle a really “tricky” case.

defined? in the context of resolv-replace

This library simply monkey-patches (IP|TCP|UDP|SOCKS)Socket classes provided by the socket library to use the Resolv DNS resolver.

In the case of SOCKSSocket, the monkey-patching only intervenes when the Ruby interpreter is compiled with the --enable-socks flag. So let’s see how the resolv-replace library handles this tricky case

Notice the modifier-if line 10. Indeed, to choose to monkey-patch this class or not, the resolv-replace library simply checks if the SOCKSSocket constant is defined using the defined? keyword. Indeed, as seen in the previous section, SOCKSSocket is only defined if the Ruby interpreter is compiled using the --enable-flag.

So, as the class keyword is only a syntactic sugar for class definition and class opening, then you can call a modifier-if to execute this code (or not).

Now let’s see how using defined? can positively impact the performances of your application.

defined?(yield) vs block_given?

If in your program you deal with a huge amount of blocks, then defined? yield can definitely become a real optimization for your program performance. Indeed, to check if a block is passed to your method, you normally use the Kernel#block_given? method

Here method_with_block_given checks if a block is passed as argument by using Kernel#block_given?. If so, then yield is called and the block is executed. Otherwise, block_given? returns false and yield is never executed.

Ruby provides another way to achieve the same result: defined?(yield)

The main difference between these 2 expressions is that defined?(yield) is faster than Kernel#block_given?. Indeed, it’s a keyword when the block_given? is a method. So block_given? is slower because of the cost of the method call added to the cost of the Method Lookup Path.

Let’s generate benchmark-ips reports to see what’s the difference between defined?(yield) and block_given?

We can see that block_given? is 1.27x slower than defined?(yield).

But as seen in the above benchmark, we’re able to call block_given 9.897M times in a second. So keep in mind that this optimization is only relevant on a huge amount of block calls.

Conclusion

defined? isn’t the most popular keyword in Ruby. Nevertheless, in some situations this keyword becomes a powerful asset to enhance your program performance or to handle tricky cases where a constant, method, etc.. is conditionally loaded. Please feel free to share with us your experience with this keyword in the comments section.

Voilà!

“The Old Pond” by Matsuo Bashō

An old silent pond

A frog jumps into the pond —

Splash! Silence again.

RubyCademy

E-Learning platform for Ruby and Ruby on Rails

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store