d

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.

15 St Margarets, NY 10033
(+381) 11 123 4567
ouroffice@aware.com

 

KMF

Best Ruby Practices Beginners Should Know

Python’s dominance is never really questioned when it comes to the best for programming novices because it checks almost every box that defines a simple language. It’s remarkably easy to pick up and can rise to any challenge. But what about Ruby?

Although it does not get enough credit for being one, Ruby is an awesome language for beginners. It provides powerful constructs (like blocks) and versatile concepts (like message passing à la Smalltalk) but retains Python’s fluid and elegant English-like syntax. In fact, in many cases, one might argue that the unique design choices that went into the Ruby syntax beat even Python in terms of readability and expressiveness. If you’re getting into programming, it’s very easy to recommend that you start with Ruby.

This article aims to establish some practices that are generally accepted by the Ruby programming community. Before we dive right into how you, as a beginner, can channel Ruby’s power, let me mention two Japanese phrases that you should hold in memory: okonomi and omakase. I promise this is relevant, and you’ll see why in a bit.

Okonomi

Ruby has always been driven by the principle to “optimize for programmer happiness” and, as a result, always offers several different ways to do the same thing, unlike Python, which has valued the philosophy of having “one and preferably only one way to do something.” As a result, many people who come to Ruby from another language find themselves baffled at the sheer number of choices the language offers for accomplishing any given task.

This is what the Japanese call okonomi, a phrase that typically applies to sushi, which translates to “I’ll choose what to order.”

Statements Are Expressions

In Ruby, there are no statements. Every line and every command is an expression that evaluates something. Even function definitions return something—the symbolized function name.

So while you cannot hold functions in variables (something Python and JavaScript allow), you can hold their identifiers as symbols and invoke them with send (more on that in a bit).

How Do You Make the Most of This?

This particular design decision leads to a few notable features, the most recognizable of which is that both the return and next keywords are, for the most part, redundant, and the recommendation is not to use them unless you want to terminate the function or block early.

Bye-Bye Brackets

In Ruby function, parentheses are, with certain caveats, optional as well. This makes Ruby ideal for defining domain-specific languages or DSLs. A domain-specific language is a language built on top of another that defines abstractions for a specific specialized purpose.

For examples of DSLs, you need not look further than Rails or RSpec but for the sake of simplicity, consider Sinatra, a straightforward web server built in Ruby. This is how a simple service would look built with Sinatra.

What’s not immediately apparent from this example is that get here, which looks very much like a language keyword, is actually a function! The get function here takes two arguments—a string path and a block that contains the code to be executed when the path matches. The return value of the block will be the HTTP response for the request matching the method and path.

How Do You Make the Most of This?

By embracing this freedom, you can define your own abstractions for your use cases. Ruby actively encourages developers to define their own little DSLs for day-to-day abstractions and write clean code by using them. The best part is that code then reads like pseudocode, which is always a good thing.

While parentheses are optional, the convention is to generally omit the parentheses only for zero or one argument, while retaining them when there is more than one, for the sake of clarity.

Method Names

Ruby enables method names to have all sorts of punctuation such as =, ?, !. Each of these punctuation has its purpose, by convention, and indicates the particular function’s nature.

Many Ruby functions come in two variants: regular and “bang.” To understand the difference, consider this example with two variants of the reverse method on strings.

In Ruby, functions with the exclamation mark in the name modify the object they are called on. In Rails, the exclamation mark indicates that the function will raise an exception if it cannot accomplish said task instead of failing silently like its non-bang counterpart.

How Do You Make the Most of This?

You should imbibe the same convention in your code so that users of the code can easily get an idea of the function’s nature.

Symbols Over Strings

The concept of symbols is something unique to Ruby. Symbols are just strings that are interned in memory and are not allocated new memory every time they are defined.

Symbols are used in tons of places across Ruby, notably as keys for hashes and constants defining identifiers and functions.

You can symbolize a string in two ways—prefixing the colon: before the string (quotes are required unless the string is a valid identifier) or invoking to_sym method on it.

How Do You Make the Most of This? 

The standard of defining hashes in Ruby is by using the “rocket operator” =>. But using hashes presents a concise, cleaner, and more JavaScript-esque way to define the same operation.

The second notation is easier to read, performs better for larger data sizes, and is widely recommended now as the preferred way to define hashes. Symbols are also used for passing messages to objects using send).

Talk Over Messages

Ruby inherits the concept of message passing from Smalltalk and goes all-in with this idea. Every method call and every variable access in Ruby is achieved by sending a message to the instance and receiving a response.

Messages are sent by using the send function (or public_send to not bypass visibility) and passing the symbol with the name of the method you want to invoke, and any arguments that function may require. Ruby also allows you to dynamically define methods using define_method (duh!) and even perform actions when a method is not defined on an object.

The above examples are the same as what you could achieve by invoking the string’s reverse and split methods. If a class responds to a message, it will perform the action or raise an exception if it doesn’t.

How Do You Make the Most of This?

Playing with this message functionality unlocks a whole new world of meta-programming that few other languages can match. You should try to use these features to remove boilerplate from your code.

Monkey Patching

This is perhaps the most controversial but also the most powerful feature of Ruby.

Monkey patching, a play on the phrases “guerrilla patching” and “monkeying about,” is the process of opening up pre-defined classes and changing their existing functionality or adding functionality to them. Ruby as a language is one of the only few that actively encourages the use of monkey patching as a legitimate way to add functionality to the language.

While languages like Python and JavaScript discourage the process, Ruby embraces it and makes it easy to extend any class or module as simple as this:

How Do You Make the Most of This?

Frameworks like Rails actively use monkey patching to add features to built-in Ruby classes like String and Integer. If used carefully and if appropriately documented, it is a powerful way of adding functionality in one location and making it available everywhere across the codebase.

Care should be taken to not overdo this and only add the most general-purpose code to the root classes.

To drive the point home, feast your eyes on monkey patched code beauty from Rails ActiveSupport. You can install it separately from Rails and see a comprehensive list of examples in their docs.

Less Is More

In the pursuit of programmer happiness, Ruby is packed to the brim with syntax sugar and method aliases focused on readability.

How Do You Make the Most of This?

You should preferably use shorthand wherever Ruby’s syntax allows it because the reduced punctuation and added conciseness make the code easier to read and process mentally.

Want to make an array of strings, symbols, or numbers? Use % notation.

There are uppercase versions of these shorthands that also allow interpolation.

Another interesting shorthand notation is when you’re trying to map or select over an array, and all you want to do is invoke a single method on all of the objects.

Many of the operations we take for granted in a programming language, like mathematical operations, are all syntax sugar notations. Since Ruby is built on message passing, any valid string is a valid method name such as + or [].

Omakase

Remember the other word I asked you to remember when we started? I promised it was relevant. Omakase is an opposite version of an okonomi meal, this time consisting of sushi selected for you by the chef. While Ruby’s offer of several ways to accomplish something boosts creativity and expression, it comes with its own set of drawbacks, especially when it comes to consistency and code review.

Based on what we’ve learned, we can make the following changes to the code:

  • monkey patch method definition into the Integer class
  • use ? in method names that have a Boolean return type
  • remove redundant parentheses ( )
  • exit early instead of indenting the entire code inside an if block
  • remove redundant return and next keywords
  • inline blocks with a single expression using braces { }
  • use from Ruby’s huge assortment of built-in functions, such as Array::none?

Using a comprehensive style guide and linter is key when getting started with programming in any new language. Not only does it improve the quality of your code, but it also provides you with an excellent way to learn by pointing out improvements in real-time as you code.

A linter will reduce the number of ways you have for writing a program, but what you lose in the creativity of expression is more than made up for inconsistency and code clarity. I would gladly make that trade-off even as a professional, much more so if I were a novice.

Let me recommend two tools that you should use as a beginner.

RuboCop

When it comes to a linter for Ruby, nothing comes even close to RuboCop. It’s a linter, formatted, and style guide rolled into one, and while it is configurable, the configuration that ships out of the box is more than enough to put you on the right track for code quality. RuboCop also helps you scan for security vulnerabilities, giving you yet another reason to set it up.

Install and try it out today. Your future self will thank you, and possibly me as well.

DeepSource

When it comes to working in a team, reviewing other people’s code becomes important. DeepSource is an automated code review tool that manages the end-to-end code scanning process and automatically makes pull requests with fixes whenever new commits are pushed, or new pull requests are opened against the main branch.

Setting up DeepSource for Ruby is extremely easy. As soon as you have it set up, it will scan your entire codebase, find scope for improvements, fix them, and open PRs for those changes.

That’s all, folks! Have fun learning Ruby; it’s a fantastic language.

Credit: Source link

Previous Next
Close
Test Caption
Test Description goes like this