How does Rubocop statically check for ruby syntax errors
You do not even need a tool like Rubocop. Ruby itself is able to check the syntax without executing the code:
$ ruby --help
Usage: ruby [switches] [--] [programfile] [arguments]
[...]
-c check syntax only
[...]
Let's check if it finds syntax error:
$ ruby -c -e "def; end"
-e:1: syntax error, unexpected ';'
Ruby reads and parses the source code first and executes in a later step. If the first step of parsing already fails because the code doesn't make any sense then executing would be impossible anyway. It is not the execution that finds syntax errors it is the parsing of the code.
But there are of course errors which Ruby doesn't find but other programming languages would detect when compiling the code. For example a TypeError
:
$ ruby -c -e "[1,2][:bar]"
Syntax OK
The syntax is fine but does this code actually work?
$ ruby -e "[1,2][:bar]"
Traceback (most recent call last):
-e:1:in `<main>': no implicit conversion of Symbol into Integer (TypeError)
Validate Ruby Syntax using Ruby
Let the code string be code
. The standard way is to do something like this:
begin
RubyVM::InstructionSequence.compile(code)
nil
rescue Exception => e
... # Put code here to return `e` itself, print its message, or whatever you like
end
If an error is raised and is rescued, that error will display the syntax error. If not (and nil
is returned), then code
is syntactically valid Ruby code (which does not guarantee that it is free of other types of errors).
The comments saying it is dangerous to do, etc, does not seem to make sense.
Getting a syntax error when checking if a value is type Integer
Try with parentheses
if !customer["age"].to_s.empty? && !customer["age"].is_a?(Integer)
How can I fix this Ruby syntax error concerning the end keyword?
I was under the impression that parentheses were optional in this instance.
Yes and no. Parentheses are indeed optional, but that doesn't mean that not using them won't change the behavior of your code, just that you won't get a syntax error.
If Ruby encounters a space immediately after a method, it will parse the rest of the line as its argument(s). So, parentheses are optional if you don't have anything on the line that isn't a part of the method argument. If you do, you have to specify what part of the line constitutes your argument list, by enclosing it in parentheses.
Here's a related potential problem to be aware of. Consider these lines, which differ by only a single space:
f(3+2)+1
f (3+2)+1
The first of these passes 5
to the function f
and adds 1
to the result. The second one passes 6
to the function f
. For the same reason: if Ruby encounters a space immediately after a method call, the rest of the line is parsed as the argument list.
I borrowed that example from Matz's book, where he eloquently calls this a "pernicious whitespace dependency." You have to be careful with spaces on method call lines.
This is the cause, also, of the error that you're getting. Ruby can't parse your line because you have two method calls in it. So the second one causes the error: Ruby is expecting the end
keyword and instead it's encountering another method call.
Adding parentheses to the second one gets rid of the syntax error:
@@colors.index array[0] * 10 + @@colors.index(array[1])
But it probably doesn't give you the result you want. It will parse it like this:
@@colors.index(array[0] * 10 + @@colors.index(array[1]))
So, use parentheses for both of them. I'm not sure what you're trying to do (not sure what you want to multiply by 10), but something like this:
@@colors.index(array[0]) * 10 + @@colors.index(array[1])
In general, I prefer to parenthesize arguments to method calls. Pretty much the only time I don't use them is with puts
, print
and p
(edit: and all those other ones I forgot about that Jörg has added in the comments below).
And be careful not to put a space between the method call and the open paren.
Related Topics
Convert a String of 0-F into a Byte Array in Ruby
How to Click on a Specific Coordinates of an Element
Simplest Way to Send Raw Byte-Arrays Using Ruby's Tcpsocket-Class
Rails Server Does Not Start by Command "Rails S"
How to Use Reference Images in SASS When Using Rails 3.1
How to Sanitize Raw SQL in Rails 4
How to Change the Locale Through Url
How to Disable Wait Time for Watir
Is There a Best Directory to Place Image Uploads on Heroku
Cannot Install Any Version of Ruby on Mojave - Internal Ranlib Command Failed
Does Ruby 1.9.2 Have an Is_A? Function
How to Render File in Rails 5 API
Best Way to Handle Dynamic CSS in a Rails App
How to Decode Q-Encoded Strings in Ruby