A Ruby interpreter is a program that reads & runs Ruby code.
But…
Did you know that the default Ruby interpreter (MRI) has lots of interesting & useful command-line options?
Like:
ruby -v
Which gives you the Ruby version you are using right now.
Or the -e
flag which allows you to run a bit of code directly, without a file & without having to go into irb
.
Like this:
ruby -e 'puts 123'
You can find these flags by using -h
.
There are some “hidden” flags you can only see with --help
.
Here’s a table of what I think are…
The most interesting flags:
Flag | Description |
---|---|
-v | Print Ruby version |
-c | Syntax check |
-e | Run code directly |
-w | Enable warnings |
-r | Requires a file / gem |
-I | Add directory to load path |
–enable frozen-string-literal | Freeze all strings |
–dump parsetree | Show parse tree |
Let’s focus on some of these flags to see how they work!
Syntax Check
If you have code & you want to know if the syntax is correct you can use the -c
CLI option.
Example:
ruby -c code_without_syntax_errors.rb # Syntax OK ruby -c code_with_syntax_errors.rb # syntax error, unexpected tIDENTIFIER, expecting end-of-input
Simple, but it works 🙂
Quick Require
Sometimes you want to temporarily require a gem into a Ruby program without having to write “require” on the top of your file.
Like a debugging gem.
Example:
ruby -rpry code.rb
Very helpful!
The Warning Flag
Using the warning flag will enable linting & show you possible problems with your code.
For example, this code:
p @test
Prints the following warning when you use ruby -w
:
warning: instance variable @test not initialized
This is a good warning!
Because you may be trying to use an instance variable without giving it a value first.
Or you may have a typo in an instance variable name, which this flag can help you find before it becomes a problem.
The fix is simple:
@test = nil
Here’s another example:
c = 1
This will give you:
warning: assigned but unused variable - c
To fix this warning you can either delete the variable or use it.
This only works for local variables.
But you should know that inside block arguments it’s considered a “best practice” to replace unused arguments with an underscore (_
).
Example:
{ chocolate: 82 }.map { |k, _| k }
This is a common convention in Ruby.
The _
is not special, it just happens to be a valid variable name.
More Warning Examples
The result of the following code isn’t being returned from a method, or assigned to any variable.
2 * 2
Ruby alerts you like this:
warning: possibly useless use of * in void context
The fix?
Delete the useless statement, or assign it to a variable.
Now let’s look at this method:
def orange(weight, quantity) # ... end
There are different ways to call orange
:
orange 100, 2 orange(100, 2) orange *[100, 2] orange(*[100, 2])
If you use orange *[100, 2]
with warnings enabled you get this:
warning: '*' interpreted as argument prefix
What’s happening?
Ambiguity.
Ruby thinks you mean orange * [100, 2]
, instead of orange *[100, 2]
.
The space between the *
& [
makes a difference because it associates the *
with the array (splat operator) if it’s missing, or it thinks *
is a method call if it’s present.
So yes, in this case, space matters.
You can fix this warning by calling the method any of the other ways.
Now:
Run some of your own code with the -w
flag & improve it by removing some warnings 🙂
Read-Eval-Print-Loop
You are probably familiar with irb & pry, they are both what we call REPLs.
Using the -n
flag combined with the -e
flag you can get a similar effect with very little code.
Here’s an example:
echo 'bacon\nchocolate\norange' | ruby -ne 'puts $_.upcase' # BACON # CHOCOLATE # ORANGE
This takes the input from echo
, then for each line it calls your code (puts $_.upcase
).
Where $_
is a special variable that contains the last input value read by gets
.
The Frozen String Literals Flag
Ruby 2.3 introduced the frozen string literals “magic comment“.
It looks like this:
# frozen_string_literal: true
This will freeze all your strings, making them immutable (can’t be changed).
Another way to do this is by passing the --enable frozen-string-literal
flag to Ruby.
This code:
str = "abcdef" str[0] = "b"
Results in this error when you use that flag:
can't modify frozen String (FrozenError)
But what if you need to change the string?
Then you can do this:
str = "abcdef".dup
or this:
str = +"abcdef"
Both give you a non-frozen string to work with.
Summary
You have learned about Ruby’s command-line options, including the version flag, the warning flag & the frozen string literals. All of these flags can be useful, give them a try!
Don’t forget to share this article so more people can benefit from it.
Thanks for reading 🙂