RubyGuides
Share this post!

All posts by Jesus Castello

ruby symbols vs strings

How Are Symbols And Strings Different?

Have you ever wondered about the differences between symbols & strings?

Let’s talk about that!

Strings are used to work with data.

Symbols are identifiers.

That’s the main difference. Symbols are not just “frozen strings“, they have different uses than strings.

When to Use Symbols

One of the most common uses for symbols is to represent method & instance variable names.

Example:

The :title after attr_reader is a symbol that represents the @title instance variable.

You can also use symbols as hash keys.

Example:

The benefits?

Symbols look better, they are immutable & if you benchmark string keys vs symbols keys you will find that string keys are about 1.70x slower.

Symbols can also be used in metaprogramming methods like send:

In Summary:

You should use symbols as names or labels for things (like methods) & use strings when you care more about the data (individual characters).

Converting Between Strings & Symbols

Sometimes you will get a symbol back from some method call & you will need to convert it into a string so you can compare it with other strings or do some other string operation.

You can do this using the to_s method.

For example, when using method_missing you get the name of the missing method as a symbol & you may want to check if this method name matches a certain pattern (like ending in ?).

Example:

You can also convert a string into a symbol.

The method to do this is String#to_sym:

Creating An Array Of Symbols

If you want to create an array of symbols you can use this code:

This saves you from having to type the colons & the commas.

Similar to the string version %w:

Ruby Symbols Video

Symbol GC

Another interesting fact about symbols is that there are different types, and the reason for that is that symbols were not garbage collected before Ruby 2.2, which means that they where not cleaned up from memory when no longer needed like regular Ruby objects (strings, hashes, arrays…).

You can see an example here:

You will notice that the total count of symbols increases by 10, just like you would expect since we are creating 10 new symbols.

But since Ruby 2.2 these symbols are removed from memory because they are just temporary & not being used by something else in this code.

If you try this code on a version of Ruby that has Symbol GC enabled both symbol counts will be the same.

Some symbols will never be removed from memory, these are called “immortal symbols”.

You can count them using the ObjectSpace module:

Notice that symbols created directly, like :a1 will automatically become immortal symbols. Creating a new method will also create an immortal_static_symbol to go with it.

So where do mortal symbols come from?

From strings converted into symbols with the to_sym method.

You can check this yourself using ObjectSpace.count_symbols.

And if you are wondering what’s an immortal_dynamic_symbol, it’s a symbol that has been promoted from mortal to immortal. This can happen when you create a method with the name of a mortal symbol.

Summary

On this article you learned:

  • Symbols are immutable
  • Symbols are not pointer to values, they are values themselves
  • Strings are for data & symbols are for identity
  • How to convert between strings & symbols
  • Symbol GC was introduced in Ruby 2.2 to clean up temporary symbols

Hope you learned something new!

Please share this post so it can reach more people 🙂

functional programming

Functional Programming In Ruby

Maybe you just heard about functional programming & have some questions.

Like…

What is functional programming exactly? How does it compare to object-oriented programming? Should you be using functional programming in Ruby?

Let me answer these questions for you so you can get a better picture.

What Is Functional Programming?

It’s not just a fad or a fancy word, it’s an actual programming paradigm that has been around for a long time but it has regained popularity recently.

And the basic ideas behind this paradigm are easier to understand than you think.

In functional programming we avoid changing state & we try to write “pure” functions.

Avoiding state change means that these functions don’t change anything outside of the function, no instance variables, no changing some object that was passed in…

None of that.

In a functional programming language (like Haskell) all data is IMMUTABLE.

There are things like variables, but they behave more like in the mathematical world. Once a variable is given a value, the compiler won’t allow you to redefine this variable with another value.

functional programming

Benefits Of Functional Programming

Immutability is the main advantage of functional programming because mutable data can lead to subtle errors that are hard to track.

Example:

In this example I want to find out if all the elements in the array are different from the first element.

To make this work we need to remove the first element from the array & at the same time save this element so we can compare it against the rest.

How can we do that?

We are working with an array & if you take a look at the list of available methods you will find that the Array#shift method does exactly what we want.

It works just fine until…

…you look at the value of arr after calling the method once:

Surprise!

The array lost one element (1) & we didn’t notice.

That’s how sneaky this kind of mutability bugs can be.

Fixed version:

Functional vs OOP

Should we all just adopt functional programming?

It may seem like all this immutable state makes functional programming the complete opposite of OOP, and in a sense it is, but there is still a way that the two programming paradigms can work together.

So no, there is no need to rush & go full-on functional programming. Ruby is designed for OOP anyway, so you would be fighting against the grain.

The good news:

You can still use the best ideas from functional programming & apply them to your Ruby code.

Reduce Mutability As Much As Possible

One way to do that is to STOP using attr_accessor, stick only to attr_reader.

After you do that then you need to keep an eye on strings, arrays & hashes.

There are methods that will change these objects:

  • Most methods ending in ! (like gsub!)
  • delete
  • update
  • clear
  • shift / unshift / pop / push

The first step is to be aware of these methods.

If you have to use one of these methods you can work on a duplicate object.

Given a string & a clone of that string:

We get these results when we clear the duplicated string:

This keeps the original string safe.

Partial Application

There is more to functional programming than immutable data & pure functions.

Like the partial application of functions, also known as “currying”.

Example:

Notice how the add method takes two arguments, but by using the curry method we can “preload” one of the arguments.

Then we get a lambda that we can call with just the 2nd argument.

Here’s another example:

One more example:

Summary

You have learned about functional programming, the core of it is pure functions & immutable data, it’s just a way to think about your code & not completely incompatible with OOP.

Thanks for reading, don’t forget to subscribe to the newsletter if you haven’t yet! 🙂

ruby string methods

Ruby String Methods (Ultimate Guide)

A string is just a sequence of characters.

Since strings are objects they have a lot of methods you can use to do things with them.

In this article you will find the most useful Ruby string methods with examples!

How to Get The String Length

Easy:

What is String Interpolation?

String interpolation allows you to combine strings together:

What some people don’t know is that you can have actual code inside the interpolation.

Probably not something you want to do often, but here’s an example:

How to Extract a Substring

If you only want part of a string, instead of the whole string, then you can use a range to extract that substring.

Like this:

The first number is the starting index & the second number is the number of characters you want.

You can also use a range if you want to do something like “get all the characters but the last one”.

Example:

In this code the first index is the starting index & the second index is the ending index (inclusive).

How to Find Out If a String Contains Another String

What’s the easiest way to find if a string is included in another string?

The include? method:

You can also use the index method:

This method looks for partial words & instead of returning true or false it will give you the index where the start of this string is found.

In this example index is finding the “day” in “Today”.

If you want to find patterns (like all the words containing the word “day”) you are looking for regular expressions.

How to Pad a Ruby String

One way to pad a string is to use the rjust method with two arguments:

If you want to pad to the right you can use ljust:

Compare Strings Ignoring Case

Since string comparison is case-sensitive you want to make sure that both your strings are in the same case.

The common way to do that is to make both sides of the equation downcase or upcase.

Example:

There is also a casecmp? method that does a case insensitive comparison, but it’s rarely used, stick with the method above.

How to Trim a String & Remove White Space

When reading data from a file or a website you may find yourself with extra white space in your string.

You can remove that extra space with the strip method:

If you only want to delete the white space from one of the sides (left / right) you can use the lstrip & rstrip methods instead.

String Prefix & Suffix

You can use the start_with? method to check if a string starts with a specific prefix.

Here’s an example:

There’s also an end_with? method:

In addition, Ruby 2.5 introduced the delete_prefix & delete_suffix methods, which may be useful to you.

Here’s an example:

Convert a String to An Array of Characters

Taking a string & breaking it down into an array of characters is easy with the split method.

Example:

By default split will use a space as the separator character, but you can pass an argument into this method to specify a different separator.

Here’s how you can split a list of comma-separated values (CSV):

But if you are working with CSV data specifically you may want to consider using the CSV class from the standard library. This class can do things like reading column headers, so it makes things easier for you.

Convert an Array to a String

If you would like to take an array of strings & join these strings into a big string you can do that using the join method.

Example:

It’s also possible to pass an argument to join, this argument is the characters separator.

Example:

Convert an String Into An Integer

If you want to convert a string like "49" into the Integer 49 you can use the to_i method.

Example:

Notice that if you try this with a string that contains no numbers then you will get 0.

Example:

Check If A String Is A Number

Would you like to know if a string is made of only whole numbers?

You can do this:

Note: The match? method was introduced in Ruby 2.4, you can use match (without the question mark) on older versions.

This code uses a regular expression, let me translate it for you:

“From the start of the string (\A) check if there is an optional dash (-?, for negative numbers), then make sure there are some numbers in there (\d+) & nothing else until the end of the string (\Z).”

How to Append Characters

You can build up a big string from smaller strings by appending characters to an existing string. We also call this string concatenation.

Here’s how to do that using the << method:

Don’t use += for this because that will create a new string every time, which is not good for performance.

Iterate Over Characters Of a String in Ruby

Sometimes it’s useful to work with the individual characters of a string.

One way to do that is to use the each_char method:

You can also use the chars method to convert the string into an array of characters. Then you can use each on this array to iterate.

Example:

How to Convert a String to Upper or Lowercase in Ruby

If you would like to convert a string to all upper case you can use the upcase method.

Example:

And if you want to convert to lower case you can use the downcase method.

Example:

How to Create Multiline Strings

You can create multi-line strings in two different ways.

One is by using heredocs:

And another is by using %Q:

How to Replace Text Inside a String

If you want to replace some text inside a string you can use the gsub method.

Let’s replace the word “dogs” with “cats”:

Notice that gsub will return a new string, if you want to apply the changes to the original string you can use the gsub! method.

The gsub method also takes regular expressions as an argument so you can replace patterns instead of exact words.

Here’s an example:

This will replace all the numbers in the string with the number 5.

There is one more way to use this method, with a block:

How to Remove the Last Character From a String

If you are asking the user for some input (using the Kernel#gets method) then you will have a newline character (\n) at the end of your string, this prevents you from comparing the string directly.

Example:

The best way to remove that extra newline character (\n) is to use the chomp method.

It’s good to know that since Ruby 2.3 this method takes an optional argument that allows you to remove the characters you want to remove.

Example:

And if the character is not there it will return the original string.

How to Change String Encodings

Strings are stored as a sequence of bytes, they are turned into the characters that you can see based on their encoding.

For example, the number 65 in the ASCII encoding represents the letter “A”.

But there are also more complex encodings, like UTF-8, which allow you to represent characters from different languages (Chinese, etc.) & even emojis.

To find out the current encoding for a string you can use the encoding method.

When reading a file from disk or downloading some data from a website you may run into encoding problems.

You can often fix that problem by enforcing the encoding.

Like this:

Summary

You learned about many string methods, like join & split to break down strings into arrays, gsub to replace text inside strings & strip to trim out extra white space.

Since you may want to reference this page later make sure to bookmark it & share it with all your Ruby friends 🙂

Ruby Loops

The Definitive Guide to Loops in Ruby

In this article you will learn many different ways to write a Ruby loop.

A loop lets you repeat some action a number of times.

You can also go over a list of things, like an array or a hash, and work with each individual element.

If you are a beginner I don’t want you to get overwhelmed by all the options. So stick with the each & times methods described here.

For my more advanced readers this will help you review & expand your toolbox of looping methods.

The Each Loop

This loop requires you to have a collection of items, like an array, a range or a hash to be able to use it.

Example:

This will print all the numbers inside the numbers array [1,3,5,7].

Notice how we have this syntax with the |n|.

In case you are not familiar with this, we call the whole thing after each a block { |n| puts n }.

A block is just a way to create a method without a name.

So what happens is that each, or any other method that takes a block, is able to use our name-less method.

And that’s how puts n is run multiple times.

If you want to use each with a hash you will need two parameters (one for the key & another for the value).

Example:

Give this a try 🙂

Each With Index

There are some cases where you want to use each but you need the index number.

You can use the each_with_index method:

The Times Loop

This is possibly the easiest loop you can come up with.

Look at this code:

This will print the word "hello" 10 times.

As you can see there isn’t much to it & it should be easy to remember.

But what if you want the number?

In the last example, with the each loop, we had access to this n so we could print it.

You can also do that with times.

Example:

This will print hello 0, hello 1, hello 2, etc.

Give it a try!

The key here is the little |i| thing, which by the way, can be anything. It doesn’t have to be an |i|. It could be |n| or |foo|, or |bacon|

It’s just a name!

If you are familiar with methods, this |n| is like a method parameter. In other words, it’s just a variable that becomes the current value for each iteration of our times loop.

Range Looping

You may have noticed that when using the times method it starts counting from 0.

This can be a bit inconvenient if you want to start with a different number.

You can use a range & the each method to have more control over the starting & ending numbers.

Example:

This will print all numbers from 1 to 10.

Ruby While Loop

The while loop is available in most programming languages so it’s always useful to know. It’s also the kind of loop that you can fall-back to when everything else fails.

And there are some situations when only a while loop would make sense. For example, if you don’t know how many times you need to loop in advance.

Here’s a code example:

This will print all the numbers from 0 to 9 (10 excluded).

Notice that there are some important components:

  • The n variable
  • The condition (n < 10)
  • The n += 1

All of these components are critical for this to work.

The variable n holds the value we are using for counting, the condition (n < 10) tells Ruby when to stop this loop (when the value of n is greater or equal to 10), and the n += 1 advances the counter to make progress.

Skipping Iterations

In all of these loop types you can skip iterations.

Let’s say that you are going over an array of numbers & you want to skip odd numbers.

You could do something like this:

The key here is the next keyword, which skips to the next loop iteration (the next number in this case).

A better way to do this is to use other methods like step & select.

Example:

Stopping Early

You can also break out of a loop early, before the condition is met, or before you go over all the elements of the collection.

The following example stops when it finds a number higher than 10:

The key here is the break keyword.

The Kernel#loop Method

The last kind of loop we are going to talk about is literally the loop method.

This method takes a block & it runs an infinite number of times.

Example:

You can stop a loop method in two ways:

  • Raising a StopIteration exception
  • Using the break keyword

Summary

You have learned many different ways to loop in Ruby! Including the times method, the each method, the loop method & the while keyword.

You have also learned how to control the loops by skipping iterations with next & breaking out of loops with break.

ruby nil

Everything You Need to Know About Nil

Nil…

What is it, really?

Well, nil is just a Ruby object.

As you can see here:

There is only one nil object, with an object_id of 4 (8 in 64 bit Ruby).

NilClass

Just like any other Ruby object nil has a set of methods.

Here’s the class definition from Rubinius:

Notice how all these to_something methods return an empty value (0 for numbers).

Empty hash, empty string, empty array…

The reason for this is that nil is used to represent “nothing”.

Where Do Nil Values Come From?

Many methods will return nil when you ask for some value but that value is not available. Product not found, array index out of bounds, hash key that doesn’t exist…

Example:

This will often lead to all sorts of problems since we expect our query to return a valid value instead of nil.

Like this NoMethodError exception:

To avoid this you will need to check if you have a nil value before you call a method on it.

Like this:

This is why Ruby 2.3 introduced the “safe navigator” operator (&.).

Example:

Depending on what object you are working with there are a few techniques you can use to avoid checking for nil values entirely.

For example, you can use the fetch method on Hash & Array objects.

Or you can use the Null Object Pattern in your own classes if you want to return a default value instead of nil.

Other Places Where Nil Is Lurking

You should be aware that instance variables that are undefined will return nil.

So watch out for that, it might just happen that you misspelt the name of your instance variable or you forgot to initialize it!

Another place where you can find nil is with the puts & print methods.

These two methods always return nil.

I mention this because I have seen some of my students try something like this:

Which results in numbers being [nil, nil, nil]. The solution in this case is to simply remove the puts from inside the block.

Null Object Pattern

No discussion about nil is complete without mentioning the Null Object Pattern.

In her excellent talk, “Nothing is Something“, Sandi Metz makes the point that while nil means “nothing” it can have a more specific meaning.

For example, if we write a method that finds products & we want to return a default product…

We can return a null product like this one:

Now if we have an array with a mix of real product objects & null products then all of these products will have the name method. This means that you will not get a NoMethodError exception.

Tip: If you can treat all your objects the same way, without having to check object type then you are taking advantage of Polymorphism.

These kind of objects are great for your presentation layer, but not so much for you controllers where you want to do something different if what you are looking for is not available, like showing an alert message, redirect, etc.

Truthiness

Another thing you need to know about nil is that it’s the only value, besides false (which is also an object), that is considered “falsy”.

Everything else in Ruby is considered true in a boolean context.

Some languages consider the number 0 as a false value, but that’s not the case in Ruby:

This is saying: “if 0 is true then print 123“.

Video

Summary

You learned that nil is just a Ruby object that represents “nothing”.

You also learned that nil & false are the only two things in Ruby that are “falsy”. Everything else is “truthy”.

If you enjoyed this post don’t forget to share it on your favorite social networks!

1 2 3 24