ruby ternary operator syntax - spacing between operator - ruby

Is the following line proper ruby syntax?
session[:id]?'foo':'bar'
(Notice there is no spacing between the operators)
This line works with all the rubies I tried (>1.8.7) but I understand there can be a misunderstanding as the ? can be part of a method identifier.
Shouldn't it be a syntax error to not put spaces arround the ternary operator?

I believe the correct forms the ternary operator are when selector is the indexed hash, because the char combination ]? is invalid for the same operator:
session[:id]?'foo':'bar'
session[:id] ? 'foo' : 'bar'
session[:id]? 'foo' : 'bar'
But if you omit the space after just the a method and the question mark, this will raise the syntax error:
session?'foo':'bar'
^
SyntaxError: unexpected ':', expecting $end
session? 'foo':'bar'
^
SyntaxError: unexpected ':', expecting $end

If a method identifier has ? as part of it, you would require an additional question mark.
> array_variable.include?('itemA') ? 'yes' : 'no'
>= "yes"
> array_variable.empty? ? 'yes' : 'no'
=> "no"
> array_variable.empty? 'yes' : 'no'
SyntaxError: (irb):10: syntax error, unexpected ':', expecting end-of-input

Related

syntax error, unexpected keyword_else, expecting ':' - RUBY

prompt("Welcome to Calculator! Enter your name:")
name = ''
loop do
name = Kernel.gets().chomp()
if name.empty()?
prompt("Make sure to use a valid name")
else
break
end
end
Not sure what I'm missing here.
I got this error messsage:
syntax error, unexpected keyword_else, expecting ':'
Try out
if name.empty?
Note that you can call methods that have no params without parentheses. Otherwise you should do name.empty?() because ? is part of the name of the method.
Anyway, your mistake is the ? after the if condition. The error message is saying you that with that ? it's trying to process a ternary operator that has this syntax
condition ? expression1 : expression2
for this reason it expects :
Line
if name.empty()?
is interpreted as ternary 'if' operator inside regular if statement:
if (name.empty() ? do_somethig : do_something_else )
and double dot is missing in your code
maybe you meant this:
if name.empty? # is equal to
if name.empty?()
Because question mark is a part of method name

Treetop seems to fail on a simple grammar (5 rules)

I am trying to write a parser for a subset of C.
The behavior of treetop is difficult to analyze on this simple (further simplified) grammar.
grammar Shyc
rule functionDef
type space identifier '(' ')' bloc
end
rule type
'int'
end
rule bloc
'{' '}'
end
rule identifier
[a-zA-Z] [a-zA-Z_]*
end
rule space
[\s]+
end
end
My test case is "int main(){}"
And the error message from treetop is :
error at line 1, column 9
failure reason : Expected [a-zA-Z_] at line 1, column 9 (byte 9) after
compiler.rb:25:in `parse': Parse error (RuntimeError)
from compiler.rb:73:in `<main>'enter
The problem is thus around identifier rule...
The version of treetop : 1.5.3 and Ruby 2.1.1
Any idea ?
The problem was that my test case was in a separate file, with a supplemental end-of-line \n at the end, and that the grammar tested here does not specify how to consume that.
Here is the code that solve the problem. As discussed here on the mailing list of Treetop, the error is weird and somehow misleading but it is difficult in general to automate the emission of a clear message.
grammar Shyc
rule functionDef
type space identifier '(' ')' bloc space?
end
rule type
'int'
end
rule bloc
'{' '}'
end
rule identifier
[a-zA-Z] [a-zA-Z_]*
end
rule space
[\s\n]+
end
end

How can I logically OR two include? conditions in Ruby?

I am starting learn Ruby, need some help with the include? method.
The below code works just fine:
x = 'ab.c'
if x.include? "."
puts 'hello'
else
puts 'no'
end
But when I code it this way:
x = 'ab.c'
y = 'xyz'
if x.include? "." || y.include? "."
puts 'hello'
else
puts 'no'
end
If gives me error when I run it:
test.rb:3: syntax error, unexpected tSTRING_BEG, expecting keyword_then or ';' o
r '\n'
if x.include? "." || y.include? "."
^
test.rb:5: syntax error, unexpected keyword_else, expecting end-of-input
Is this because the include? method cannot have handle logic operator?
Thanks
The other answer and comment are correct, you just need to include parenthesis around your argument due to Ruby's language parsing rules, e.g.,
if x.include?(".") || y.include?(".")
You could also just structure your conditional like this, which would scale more easily as you add more arrays to search:
if [x, y].any? {|array| array.include? "." }
puts 'hello'
else
puts 'no'
end
See Enumerable#any? for more details.
It's because of Ruby parser, it can't recognize the difference between the passing an arguments and logical operators.
Just modify your code a little bit to distinguish the arguments and operator for Ruby parser.
if x.include?(".") || y.include?(".")
puts 'hello'
else
puts 'no'
end

Ruby Regexp Interpolation / Character Class / Global Variable Syntax Clash?

Why does this error occur?
Regexp.new("[#$]")
# => SyntaxError: (irb):1: syntax error, unexpected $undefined
# => Regexp.new("[#$]")
# ^
# (irb):1: unterminated string meets end of file
# from ~/.rvm/rubies/ruby-1.9.3-p194/bin/irb:1:in `<main>'
This should describe the subset of strings consisting of either a single $ or #, literally. And, AFAIU Ruby's Regexp engine, # and $ don't need to be escaped inside a character class even though they're usually metacharacters.
I would guess from the error message that Ruby is trying to interpolate $ when it's hitting # within double-quotes, but...why? Ordering is important. The $ and # characters have multiple overloaded behaviors, so I'm at a loss about what's triggering this.
PS, FYI:
/[#$]/
# => SyntaxError: (irb):1: syntax error, unexpected $undefined
/[$#]/
# => /[$#]/
Regexp.new '[$#]'
# => /[$#]/
Regexp.new '[#$]'
# => /[#$]/
Regexp.new "[#$]"
# => SyntaxError: (irb):1: syntax error, unexpected $undefined
The problem is not $, but #, as #... is usually used for variable expansion in double quoted strings. Like "#{x}".
But the thing is you can also expand global variables directly using #$global, and that explains your problem:
$global = "hello"
"#$global"
=> "hello"
So the solution is to escape either # or $, as this will break the string interpolation state machine out of it's effort to interpret the construct as an interpolation:
puts "\#$global"
=> #$global
puts "#\$global"
=> #$global
EDIT
And just to make it really clear :) The problem is not the Regexp, but you are trying to expand a global variable named $] when you type "#$]":
puts "#$]"
SyntaxError: (irb):22: syntax error, unexpected $undefined
To fix it you need to escape something:
puts "\#$]"
=> #$]

Adding things inside while loop causes syntax error

I'm trying to read and process lines from a file in Ruby.
I have a while loop that reads each line. If the all the while loop does is split the lines, it works fine. When I add a regex matching clause, I get a syntax error, unexpected kEND
and syntax error, unexpected $end, expecting kEND
Specifically, here is the code which "compiles"
def validate
invalid = 0
f = File.open(ARGV[0], "r")
while (line = f.gets)
vals = line.split(",")
end
end
if (ARGV[1] == "validate")
validate
end
while this code
def validate
invalid = 0
f = File.open(ARGV[0], "r")
while (line = f.gets)
vals = line.split(",")
match0 = Regexp.new(/0-9]{1,4}/)
unless (match0.match(vals[0]))
invalid ++
end
end
end
if (ARGV[1] == "validate")
validate
end
throws the error
schedule.rb:10: syntax error, unexpected kEND
schedule.rb:18: syntax error, unexpected $end, expecting kEND
The syntax error is not due to the regex. It's due to the "++". Ruby doesn't have the "++" operator. Instead, you should use:
invalid += 1
Besides, there is a bracket missing in your regexp (character class).
/0-9]{1,4}/
It should read
/[0-9]{1,4}/
There is no C-style increment/decrement operator. Instead use
invalid = invalid + 1
or
invalid += 1

Resources