- The article was translated from the article Magic Comments in Ruby by @farsi_mehdi .
In this article, we will explore the following topics:
- Comments and magic comments
- Specifications
- The existing magic comments
Comments vs. Magic Comments
In Ruby, you can annotate and record your code with comments
.
To declare a we use the # character followed by our comment
To declare a comment, we use the #
character followed by our comment.
1 2 3 4 | <span class="token comment"># Polylithic linked list structure</span> <span class="token keyword">class</span> <span class="token class-name">LinkedList</span> <span class="token keyword">end</span> |
Here, all the following text #
not interpreted by Ruby. It only helps developers understand the code.
On the other hand, there are some comments
are interpreted by Ruby. These are called Magic Comments
, or magic instructions
.
1 2 3 4 | <span class="token comment"># encoding: big5</span> <span class="token string">''</span> <span class="token punctuation">.</span> encoding <span class="token comment"># => #<Encoding:Big5></span> |
Here, # encoding: big5
is interpreted by Ruby.
When Ruby reads this magic comment
, it will automatically set an encoding of any string declared in this file to Encoding:Big5
– we will go deeper into encoding:
in the end of this article.
Specifications
Let’s take a look at the implicit rules we need to know in order to get the most out of this feature.
Syntax
There are two syntaxes for declaring a magic comment:
1 2 3 | <span class="token comment"># encoding: UTF-8</span> <span class="token comment"># -*- encoding: UTF-8 -*-</span> |
Both syntaxes will be explained similarly by Ruby.
Many files
Let’s take a look at the scope of a magic comment.
1 2 3 4 5 6 | <span class="token comment"># encoding: big5</span> <span class="token string">''</span> <span class="token punctuation">.</span> encoding <span class="token comment"># => #<Encoding:Big5></span> <span class="token keyword">require</span> <span class="token string">'./world.rb'</span> |
1 2 | <span class="token string">''</span> <span class="token punctuation">.</span> encoding <span class="token comment"># => #<Encoding:UTF-8></span> |
As we can see, magic commen only takes effect in the declared file. Indeed, the encoding in the world.rb
file is Ruby’s default encoding: encoding: UTF-8
.
Therefore, magic comments have no impact on the required files.
Many magic comments
We can create multiple magic comments in the same file
For example:.
1 2 3 | <span class="token comment"># encoding: big5</span> <span class="token comment"># frozen_string_literal: true</span> |
Here, Ruby will analyze and process both magic comments – we will go into details about these magic comments in the next section.
So both lines are effective in this file.
Priority
Because the priority rules are different for each magic comment, I will describe these rules under each magic comment.
Now that we are more familiar with the concept of magic comments, let’s look at the various magic comments we can use together.
Magic Comments
In this section, we will talk about each magic comment. We go into each of the concepts.
The goal here is to show you magic comments and give you the priority rules that apply to them. You need to see the official documentation for more information, etc.
encoding:
magic comment
In Ruby, the default encoding for any string is UTF-8
.
Read The Evolution of Ruby Strings from 1.8 to 2.5 if you are not familiar with the concept of codepoint
and encoding
.
encoding:
magic comment allows us to modify the default encoding in the file where this comment is located.
1 2 3 4 | <span class="token comment"># encoding: big5</span> <span class="token string">''</span> <span class="token punctuation">.</span> encoding <span class="token comment"># => #<Encoding:Big5></span> |
We can see that our string Encoding:Big5
is Encoding:Big5
– as declared in the magic comment. Priority
1 2 3 4 5 6 | <span class="token comment"># encoding: big5</span> <span class="token comment"># encoding: iso-8859-2</span> <span class="token comment"># coding: binary</span> <span class="token string">''</span> <span class="token punctuation">.</span> encoding <span class="token comment"># => #<Encoding:Big5></span> |
Here, only comment encoding:
the first declaration is processed. Other lines are ignored. Note that we can use encoding:
or coding:
Another familiar type: frozen_string_literal:
This magic comment is quite useful when you declare a similar string multiple times using string.
Indeed, it performs optimization by creating only one object per string, based on the content, in ruby there is a similar concept as symbol
.
1 2 3 4 5 | <span class="token comment"># frozen_string_literal: true</span> p <span class="token string">'key'</span> <span class="token punctuation">.</span> object_id <span class="token comment"># => 70306598556120</span> p <span class="token string">'key'</span> <span class="token punctuation">.</span> object_id <span class="token comment"># => 70306598556120</span> |
Here, we can see that if we declare two strings that are similar, only one instance of the String
class will be created for both strings. This mechanism is especially useful when we use strings as identifiers for resources, similar to a symbol. Priority
1 2 3 4 5 6 | <span class="token comment"># frozen_string_literal: false</span> <span class="token comment"># frozen_string_literal: true</span> p <span class="token string">'key'</span> <span class="token punctuation">.</span> object_id <span class="token comment"># => 70306598556120</span> p <span class="token string">'key'</span> <span class="token punctuation">.</span> object_id <span class="token comment"># => 70306598556120</span> |
Here, only the command is declared frozen_string_literal:
finally processed. The others are ignored.
warn_indent:
magic comment
This comment works similar to the command line output ruby -w warn_indent.rb
.
1 2 3 4 5 | <span class="token comment"># warn_indent: true</span> <span class="token keyword">def</span> h <span class="token keyword">end</span> <span class="token comment"># bad indentation</span> |
1 2 3 | $> ruby warn_indent.rb warn_indent.rb:4: warn: mismatched indentations at 'end' with 'def' |
Here, we can see that if the code is not indented well, Ruby will issue a corresponding warning. Order of precedence Here, only the warn_indent:
last command is processed. Others will be ignored.