Ruby Tuesday – String#intern

Today’s Ruby Tuesday covers String#intern.

If you are not familiar with the concept of interning, it is when the programming language/vm uses the same reference instead of multiple copies of equal objects. This is able to be done by having immutable objects, and knowing that if two objects are the same, it is safe to represent them as the same exact thing.

In Ruby String objects are mutable, so they must be compared by using an equality operator, and they get different object ids, since they can be changed at any time.

Enter String#intern. String#intern locks down a string, and creates an immutable object that represents that string, and which reference can be re-used where ever that interned string is needed.

And the result of interning a string in Ruby? A symbol.

# => :foo
# => :bar

The benefit of using String#intern in addition to being able to create symbols from a dynamic set of shared data, such as CSV or database table headers, is that it gives you as the developer a nice way to create some complex symbols without needing to worry about the correct way of quoting a symbol as well.

# => :Bar
'string with spaces'.intern
# => :"string with spaces"
'comic cursing: @*%$*^!!!'.intern
# => :"comic cursing: @*%$*^!!!"
# => :"""
# => :"'"

As we can see below, that every time we reference the string "foo", it creates a new object for that string, as seen by the different object_ids for x, y, and z. But once we intern them, even though they were different objects, they share the same interned object.

x = "foo"
=> "foo"
y = "foo"
=> "foo"
z = "foo"
=> "foo"
=> 70297488464940
=> 70297488429980
=> 70297488410060
=> 592808
=> 592808
=> 592808

String#intern is also aliased as String#to_sym.

=> :foo
=> :bar

I wanted to highlight this as String#intern instead of String#to_sym, as having an understanding about interning is something that is useful beyond just Ruby String objects, and is applicable across multiple programming languages.


Leave a Reply

Your email address will not be published. Required fields are marked *