Ruby If Elsif Else block syntax - ruby

What's wrong with this block?
if item.nil?
found = true
elsif item[:name] == name && item[:category] == category
found = true
else
i++
end
When I do syntax checking, I get
syntax error, unexpected keyword_end
but if I delete end then I get
syntax error, unexpected end-of-input

The problem is here:
i++
Ruby doesn't have a ++ operator. What you want is this:
i += 1
I believe the reason for that specific error is that Ruby is interpreting the second + as a unary + operator, i.e. the "positive number sign" (because it's the only thing that makes sense in that context), and so expects the next token to be a number†, e.g. (parentheses for clarity):
i + (+5)
...but the next token is end, ergo the syntax error.
†Or something else that responds to the +# method.

Related

Writing a Ruby class method and getting unexpected token kEND error

I am writing a class, Wrapper, and am giving it a class method self.wrap. I am getting an unexpected end-of-input error. I have been staring at the code forever and can't see where the mistake might be. I think I have all of my end's in place. What am I missing?
require 'pry'
class Wrapper
def self.wrap(input_string, column_number)
position = 0
num_inserted = 0
while (position + column_number < line.length) do
last_space_index = input_string.rindex(" ", position + column_number)
if last_space_index > position - 1
input_string[num_inserted + last_space_index] = "\n"
else
input_string.insert(num_inserted + position + column_number, "\n")
position += column_number
num_inserted ++
end
end
end
end
There is no ++ operator in Ruby.
Instead, you can write:
num_inserted = num_inserted + 1
Or for short:
num_inserted += 1
The error message you're seeing is admittedly quite confusing/misleading.
However, if you use an IDE with language-aware syntax highlighting (something I would highly recommend all programmers, in all languages, set up as a high priority for development) then this should at least highlight exactly which line of code is causing the problem.
For example, entering your code in my local setup reveals the error:
`+' after local variable or literal is interpreted as binary operator
even though it seems like unary operator

Unclear syntax error in Ruby : "syntax error, unexpected end" when using an invalid operator

I am trying to make sense of why Ruby reported the syntax error that it did , and why it could not be more clear. The following code snippet is giving me a "syntax error, unexpected end"
# #param {NestedInteger[]} nested_list
# #return {Integer}
def depth_sum(nested_list)
queue = Queue.new
nested_list.each { |element| queue.enq element }
result = 0
level = 1
until queue.empty?
size = queue.size
size.times do
element = queue.pop
if element.is_integer
result += level * element.get_Integer
else
element.each { |elem| queue.enq(elem) }
end
end
level++
end
end
I then figured out that Ruby does not have the ++ operator , so i replaced level++ with level+=1 and the code worked. But why was Ruby's syntax error message so cryptic about an unexpected end when in fact my error was not due to the "end" but because I was using a ++ operator which is not used in Ruby.
In Ruby, it is allowed to have whitespace between an operator and its operand(s). This includes newlines, and it includes unary prefix operators. So, the following is perfectly valid Ruby:
+
foo
It is the same as
+ foo
which is the same as
+foo
which is the same as
foo.+#()
The following is also perfectly valid Ruby:
foo++
bar
It is the same as
foo ++ bar
which is the same as
foo + + bar
which is the same as
foo + +bar
which is the same as
foo.+(bar.+#())
So, as you can see, the line
level++
on its own is not syntactically invalid. It is the end on the next line that makes this invalid. Which is exactly what the error message says: you are using the unary prefix + operator, so Ruby is expecting the operand, but instead finds an end it was not expecting.

Ruby: unexpected end-of-input, expecting keyword_end for if statement

I was working with Java for a few months and am transitioning back to Ruby now. I am getting a weird error from the following code:
def count_divisors
divisor_hash = {}
25.times do |i|
divisor_hash[i] = find_dividends(i)
end
puts divisor_hash
end
def find_dividends(i)
count = 0
1000.times do |k|
if i % ( k + 1 ) == 0
count++
end
end
count
end
count_divisors()
This code is generating the following error:
test.rb:14: syntax error, unexpected keyword_end
test.rb:19: syntax error, unexpected end-of-input, expecting keyword_end
This error does not occur when I remove the if statement. I am not sure why. I know every if statement needs an end statement, for some reason it seems upset by the placement of that end statement though.
Change the count++ to count += 1 Ruby does not support incremental operator.

Ruby '{x}' block works, but 'do |x|' block does not?

I'm writing a method and for some reason it's throwing an error whenever I run an each block like this:
array.each do |i|
something_on_i
end
But, it's not throwing an error when I do the same thing like this:
array.each {|i| something_on_i}
Why? I thought the two were identical.
Here's the full code:
Working:
def factor(num)
i=2
factors=[1]
while i<=num
if (num % i == 0)
factors << i
end
i+=1
end
return factors
end
def Division(num1,num2)
facs1=factor(num1)
facs2=factor(num2)
common=[]
***facs2.each {|i| common << i if facs1.include?i}***
return common.max
end
# keep this function call here
# to see how to enter arguments in Ruby scroll down
Division(STDIN.gets)
Not working:
def factor(num)
i=2
factors=[1]
while i<=num
if (num % i == 0)
factors << i
end
i+=1
end
return factors
end
def Division(num1,num2)
facs1=factor(num1)
facs2=factor(num2)
common=[]
***facs2.each do |i|
if facs1.include?(i)
common << i
end
end***
return common.max
end
# keep this function call here
# to see how to enter arguments in Ruby scroll down
Division(STDIN.gets)
The error I get is:
(eval):334: (eval):334: compile error (SyntaxError)
(eval):323: syntax error, unexpected kDO_COND, expecting kEND
facs2.each do |i|
^
(eval):324: syntax error, unexpected tIDENTIFIER, expecting kDO or '{' or '('
(eval):334: syntax error, unexpected kEND, expecting $end
Thanks to the great help in the comments from everyone, it appears this is just an issue with Coderbyte and Repl.it, rather than an issue with the code itself. The code runs just fine in irb. #Darek Nedza pointed out that Coderbyte and Repl.it are only running Ruby 1.8.7, which is likely the problem.
Solution:
For strange errors on Repl.it or Coderbyte, just double check in irb

Ruby Syntax Sugar on Addition Methods

Quick question, why this doesn't work?
sum = {}
e = "a"
(sum[e] ||= 0) += 1
I got (expecting 1):
SyntaxError: unexpected tOP_ASGN, expecting $end
(sum[e] ||= 0) += 1
When you do (sum[e] ||= 0) the parentheses cause the expression to be evaluated. As a result, it'll evaluate to the value of sum[e] (e.g. 0), which you cannot do a += operation on. It won't return an lvalue/reference to sum[e] as you might expect.
You can verify this by doing the same operation on what would be the result:
irb(main):001:0> 0 += 1
SyntaxError: (irb):1: syntax error, unexpected tOP_ASGN, expecting $end
Or even something like this:
irb(main):004:0> (sum[e]) += 1
SyntaxError: (irb):4: syntax error, unexpected tOP_ASGN, expecting $end
If for some reason you want to keep it on one line, you can do something like this:
sum[e] ||= 0; sum[e] += 1
As dbenhur mentioned, if you are going to be doing this a lot, you can also set a default value for all keys in the hash:
sum = Hash.new(0)
Sets sum to be a hash where every key is automatically set to 0 when you access it.

Resources