I'm baffled why I have a syntax error using '&&' when combining two conditions that should be true before the program can continue. I'm new to ruby and have not had a chance to actually code a complete program by myself.
I am just updating an old program and following through whatever code that is similar to what I need to update it with.
Here's my code:
def drug_dispensation_condition(charge)
return true if ['250','251'].include? charge[:rev_code]
return true if ['981262'].include? charge[:cdm_code]
return true if ['300'].include? charge[:rev_code] && ['86580'].include? charge[:cdm_code] #this line is inserted
false
end
Here's my error message:
syntax error, unexpected tIDENTIFIER, expecting keyword_end
(syntaxerror) ...e] && ['86580'].include? charge[:cdm_code]
I added the 3rd "return true" clause to include the rev_code 300 and the cdm_code 86580.
I need both the rev_code 300 and the cdm_code 86580 to declare the statement as True, so I needed to add the "&&" in between them. It looked like it was expecting the "end" after "charge[:rev_code]" instead of the 2nd condition.
Is there any other way of coding this to avoid the syntax error?
As it's a one-line statement, wrap the include? arguments in parenthesis:
return true if ['300'].include?(charge[:rev_code]) && ['86580'].include?(charge[:cdm_code])
I think you could make it a little bit more readable:
def drug_dispensation_condition(charge)
if ['250', '251', '300'].include?(charge[:rev_code]) ||
['981262', '86580'].include?(charge[:cdm_code])
return true
end
false
end
Related
I often face the situation when if condition A (for example !#object.nil?) is false, condition B, when checked, can raise an error (for example #object.some_method -> undefined method 'some_method' for nil:NilClass).
I tested it in console, but could't get some full data.
1) Is it safe to use and/&& when if first conditional is false, second can lead into an error?
2) What about or?
!#object.nil? && #object.some_method
#object && #object.some_method
Both of the above are valid patterns in Ruby. You will not get the "undefined method for nil" error, because the expression to the right of the && is never evaluated if the expression to the left of it evaluates to nil (or false).
You can also accomplish this check using postfix if or unless:
#object.some_method if #object
or
#object.some_method unless #object.nil?
are both valid alternatives.
Regarding or:
Using || (Rubyists generally avoid the keyword or operator) will not protect you from the error, because when the expression on the left side of the || evaluates to nil, the interpreter will actually continue on and attempt to evaluate the expression on the right side.
Second part of these lines will never be exected:
false && raise "this will never be raised"
true || raise "this will never be raised"
In your case, if you are using active support, you can do:
#object.try!(:some_method)
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.
When I use a shortened if/else statement with Sinatra commands, I receive a syntax error:
request.cookies['blog'].nil? ? erb :blog : redirect '/done'
Returns this error:
/home/sinatra/ptt/ptt.rb:107: syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '(' request.cookies['blog'].nil? ? "erb :blog" : redirect '/done' ^
Both of the statements produce errors when by themselves (without Sinatra code as the other statement).
Is this a Sinatra problem or is the syntax incorrect?
The error does not occur when the true/false statements are plain Ruby:
request.cookies['blog'].nil? ? foo = 1 : bar = 2
I think Ruby can't decide what is a method call and what belongs to the if statement. Try this:
request.cookies['blog'].nil? ? erb(:blog) : redirect('/done')
I am puzzled that Ruby 1.9 (JRuby 1.6.6 (RUBY_VERSION == "1.9.2") and Ruby 1.9.3-p125) give a syntax error for puts(true and false).
I don't know why - what is the problem here? How would I write that piece of code correctly? puts(true && false) works but is there a solution with and?
Example irb session:
1.9.3p125 :001 > puts(true and false)
SyntaxError: (irb):1: syntax error, unexpected keyword_and, expecting ')'
puts(true and false)
^
from /home/fr/.rvm/rubies/ruby-1.9.3-p125/bin/irb:16:in `<main>'
1.9.3p125 :002 > puts(true && false)
false
=> nil
Thanks to Mladen Jablanović for simplifying the example. The old example was f(true and f(false)).
It's all about precedences "and" and "&&" does not have the same precedeces on operands, try using
f((true and f(false)))
'and' should be used for something like "do stuff A if this worked ok then do stuffs B" and not for strict boolean checking.
check_db(param) and connect_db(param)
The operator precedence in ruby is && before = before and. So in your example using and, it would try to make this (implicit) assignment:
puts(true
and then combine it with
false)
via and, which causes the syntax error. See a great explanation here: Difference between "and" and && in Ruby?
EDIT: I'm not sure if my "implicit assignment" makes sense - think of this statement to make it explicit:
foo = puts(true and false)
EDIT 2: Remember that a method call is really called on an object. So the equivalent statements for the two cases would be:
Object.send("puts", true && false) # this works
Object.send("puts", true and false) # this is a syntax error
Object.send("puts", (true and false)) # works again
Not sure if that helps any more - you're right, it's a bit counter-intuitive. My solution is to stay away from and :)
Experimenting with the conditional operator in ruby,
def nada
false ? true : nil
end
def err
false ? true : raise('false')
end
work as expected but
def reflection
false ? true : return false
end
produces a syntax error, unexpected keyword_false, expecting keyword_end
def reflection
false ? true : return(false)
end
and attempted with brackets syntax error, unexpected tLPAREN, expecting keyword_end
yet
def reflection
false ? true : (return false)
end
works as expected, and the more verbose if...then...else...end
def falsy
if false then true else return false end
end
also works as expected.
So what's up with the conditional (ternary) operator?
You can use it like this, by putting the entire return expression in parentheses:
def reflection
false ? true : (return false)
end
Of course, it does not make much sense used like this, but since you're experimenting (good!), the above works! The error is because of the way the Ruby grammar works I suppose - it expects a certain structure to form a valid expression.
UPDATE
Quoting some information from a draft specification:
An expression is a program construct which make up a statement (see 12
). A single expression can be a statement as an expression-statement
(see 12.2).12
NOTE A difference between an expression and a statement is that an
expression is ordinarily used where its value is required, but a
statement is ordinarily used where its value is not necessarily
required. However, there are some exceptions. For example, a
jump-expression (see 11.5.2.4) does not have a value, and the value
of the last statement of a compound-statement can be used.
NB. In the above, jump-expression includes return among others.
I think this is all related to the ruby parser.
ruby parses return as the else-expression of the ternary operator
ruby is then surprised when it finds false instead of end
wrapping return false in parentheses causes ruby to interpret the entire thing as the else-expression
return(false) doesn't work because ruby is still trying to interpret just the return part as the else-expression, and is surprised when it finds a left-parenthesis (updated)
Note: I don't think this is a great answer.
A great answer could, for example, explain the parse errors with reference to the ruby grammar.
The ternery operator is just that, an operator. You don't return from it. You return from functions. When you put a return in an if, you return from the function that the if is in. Since there is no variable awaiting assignment from the result of the if, there is no problem. When you return from the ternery operator, there is no value assigned to the variable.