why cant I do this in ruby? - ruby

if !row[0].include? 'Changed database' || !row[0].starts_with? '---' || !row[0].include? "rows affected" || !row[0].nil? || !row[0] == ""
if i do
if !row[0].include? 'Changed database'
it works well but if i do multiple conditions then it fails on this error
SyntaxError: /Users/tamer/Sites/active/app/models/account.rb:42: syntax error, unexpected tSTRING_BEG, expecting kTHEN or ':' or '\n' or ';'
...ase' || !row[0].starts_with? '---' || !row[0].include? "rows...

Sometimes the parser can't guess at how you're grouping arguments.
In your example, it's interpreting 'Changed database' || !row[0].starts_with? as the argument passed to include?, and is choking when it comes across the next token, '---', which then makes no sense.
Adding parentheses to clear up the ambiguity will solve the problem, e.g.:
if !row[0].include?('Changed database') || !row[0].starts_with?('---') || !row[0].include?("rows affected") || !row[0].nil? || !row[0] == ""
If you really, really hate parentheses, you could also switch to using or instead of ||, which has a weaker precedence and will be applied later, e.g.:
if !row[0].include? 'Changed database' or !row[0].starts_with? '---' or !row[0].include? "rows affected" or !row[0].nil? or !row[0] == ""

Related

What is the idea in this bash statement ( command || true )?

I saw the following bash statement being used on the internet:
PYTHON_BIN_PATH=$(which python || which python3 || true)
I understand that if which python fails, then which python3 will be executed, but I don't understand the purpose of the true at the end of the condition. Any idea?
try running:(Note the bla)
which python_bla || which python3_bla_bla || true
echo $?
0
You will get RC=0. It means it a construct to successfully proceed to next command. Here we know python_bla or python3_bla_bla does not exist,but still command gave rc=0
Example: Check the RC of following three commands, I have changed the spelling of date command to incorrect but true is causing RC to remain 0.
date;echo $?
Thu Nov 9 01:40:44 CST 2017
0
datea;echo $?
If 'datea' is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf datea
127
datea||true;echo $?
If 'datea' is not a typo you can use command-not-found to lookup the package that contains it, like this:
cnf datea
0
Note: You can also use : operator instead of true to get the same results.Example:
command || :
To be more rigorous I guess.
for example:
if aaa isn't an existed global binary file.
After executing which aaa,you can execute echo $? and the result is 1.
But if you execute which aaa | true the result will be 0.
Simple. It will check either your system has out of the box python(version of python which has come with your O.S) or it has python version 3 in it. It will also confirm python's executable path too, you could simply print variable named PYTHON_BIN_PATH by doing echo "$PYTHON_BIN_PATH" and could check it too once.
EDIT: Here is a simple example to understand. Let's say we have a variable named val with NULL value and we do this:
echo $val || true
Output will be NULL then as it's previous command didn't give any output.
Let's say we have val=4 then we run it as follows.
val="4"
echo $val || true
4
The idea is to set the PYTHON_BIN_PATH to nothing if both which fails.
Visibly there is no difference between
PYTHON_BIN_PATH=$(which python || which python3 || true)
and
PYTHON_BIN_PATH=$(which python || which python3)
But running the command alone makes things more obvious. Suppose that python doesn't exist on the system.
$(which python || which python3)
echo $? #Returning the exit status of the previous command
1 # A non zero status generally means the previous statement failed
$(which python || which python3 || true)
echo $?
0
In short, using true at the end always give a zero exit status for
$( command || true )

Check environment variable in Chef only-if guard

I am trying to add a conditional guard to a Chef recipe action, so that it only runs if a certain environment variable is set (CLEAN_DB).
execute "create databases" do
Chef::Log.info("Cleaning/creating the database")
command "psql --file #{node['sql-directory']}/sql/db_create.sql"
cwd node['sql-directory']
action :run
user node['postgresql-user']
only-if (ENV['CLEAN_DB'] == "create")
end
The line right before the end is giving me trouble. It gives the following syntax error:
...
SyntaxError
-----------
/home/centos/.jenkins/workspace/test1__Deploy/cache/cookbooks/recipes/app_linux.rb:157: syntax error, unexpected end-of-input, expecting keyword_end
...
I've tried all the following:
only-if ENV['CLEAN_DB'] == "create"
only-if { ENV['CLEAN_DB'] == "create" }
only-if '("#{ENV[\'CLEAN_DB\']}" == "create")'
only-if 'if [[ "$CLEAN_DB" == "create" ]] ; then echo 0 ; else echo 1; fi;'
only-if 'if [[ "$CLEAN_DB" == "create" ]] ; then echo 0 ; else echo 1; fi'
And none of them seem to work. The documentation (https://docs.chef.io/resource_common.html) seems to suggest that all I need is a shell script that outputs 0 (in the shell case, it gives an error about a string literal in the condition) or a Ruby block (shown in the examples between {}). I am out of ideas at this point.
If you would have correctly spelled it only_if, then you should at least have succeeded with the second try (of the last block).
The correct syntax would be:
execute "create databases" do
# Logging here makes IIRC no sense because it's emitted at compile time
# Chef::Log.info("Cleaning/creating the database")
command "psql --file #{node['sql-directory']}/sql/db_create.sql"
cwd node['sql-directory']
action :run
user node['postgresql-user']
only_if { ENV['CLEAN_DB'] == "create" }
end
Alternatively, you can use
only_if do ENV['CLEAN_DB'] == "create" end

Issue with echo in shell script

getting issue with echo output.
line=table_name
echo "SELECT CASE WHEN FORMAT_TYPE LIKE '%character%' THEN 'replace(replace(replace('||ATTNAME||',''\'',''\\''),''"'',''\"''),''|'',''\|'') as '||ATTNAME||',' ELSE ATTNAME||',' END FROM _V_RELATION_COLUMN WHERE NAME = '$line' ORDER BY ATTNUM;"
Output I am looking for something like below:
SELECT CASE WHEN FORMAT_TYPE LIKE '%character%'
THEN 'REPLACE(REPLACE(REPLACE('||ATTNAME||',''\'',''\\''),''"'',''\"''),''|'',''\|'') AS '||ATTNAME||','
ELSE ATTNAME||','
END
FROM _V_RELATION_COLUMN WHERE NAME IN ('table_name')
ORDER BY ATTNUM;
But getting there error as
-bash: syntax error near unexpected token `)'
You need to escape the double quotes in your string
Try
echo "SELECT CASE WHEN FORMAT_TYPE LIKE '%character%' THEN 'replace(replace(replace('||ATTNAME||',''\'',''\\''),''\"'',''\\\"''),''|'',''\|'') as '||ATTNAME||',' ELSE ATTNAME||',' END FROM _V_RELATION_COLUMN WHERE NAME = '$line' ORDER BY ATTNUM;"
Note that to print an escape you have to escape the escape.
e.g
If you want \"
You need to type \\\"

Beginner Ruby Syntax Error with hash

My code seems to not be working because I'm mishandling a hash...
There's two sections in my code where I reference the hash, and two distinct syntax errors that I haven't resolved through googling.
First Section Syntax Error & Code:
"syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('"
def showBoard
puts " 1 2 3"
puts " A #{#spaces["A1"]} | #{#spaces["A2"]} | #{#spaces["A3"]}"
puts ---------------------------
puts " B #{#spaces["B1"]} | #{#spaces["B2"]} | #{#spaces["B3"]}"
puts ---------------------------
puts " C #{#spaces["C1"]} | #{#spaces["C2"]} | #{#spaces["C3"]}"
puts ---------------------------
end
Second Section Syntax Error & Code:
"syntax error, unexpected =>, expecting keyword_end"
def checkGame?
if
"A1"=>"X" && "A2"=>"X" && "A3"=>"X" ||
"B1"=>"X" && "B2"=>"X" && "B3"=>"X" ||
"C1"=>"X" && "C2"=>"X" && "C3"=>"X" ||
"A1"=>"X" && "B1"=>"X" && "C1"=>"X" ||
"A2"=>"X" && "B2"=>"X" && "C2"=>"X" ||
"A3"=>"X" && "B3"=>"X" && "C3"=>"X" ||
"A1"=>"X" && "B2"=>"X" && "C3"=>"X" ||
"A3"=>"X" && "B2"=>"X" && "C1"=>"X"
puts player1 + " wins!"
checkGame == true
elsif
"A1"=>"O" && "A2"=>"O" && "A3"=>"O" ||
"B1"=>"O" && "B2"=>"O" && "B3"=>"O" ||
"C1"=>"O" && "C2"=>"O" && "C3"=>"O" ||
"A1"=>"O" && "B1"=>"O" && "C1"=>"O" ||
"A2"=>"O" && "B2"=>"O" && "C2"=>"O" ||
"A3"=>"O" && "B3"=>"O" && "C3"=>"O" ||
"A1"=>"O" && "B2"=>"O" && "C3"=>"O" ||
"A3"=>"O" && "B2"=>"O" && "C1"=>"O"
puts player2 + " wins!"
return true
checkGame == true
elsif
"A1"!=" " && "A2"!=" " && "A3"!= " " &&
"B1"!=" " && "B2"!=" " && "B3"!= " " &&
"C1"!=" " && "C2"!=" " && "C3"!= " "
puts "It's a draw. :/ "
checkGame == true
end
return false
end
What's going wrong?
The problem with the first section is
puts -------
You probably meant to enclose the dashes in quotes, to make it a string.
The => (hashrocket) operator is only used when declaring a new hash (for example {"a" => 1}) but your second bit of code is using it outside of that context ( I'm not sure what you were trying to do so can't really suggest anything). There's a few other things that don't make sense too - you're comparing string literals at the bottom , and I suspect that the precedent of || and && won't do what you want, whatever that is

What's wrong with my array initialization in ruby?

Why is this a syntax error in ruby?
#!/usr/bin/ruby
servers = [
"xyz1-3-l"
, "xyz1-2-l"
, "dws-zxy-l"
, "abcl"
]
hostname_input = ARGV[0]
hostname = hostname_input.gsub( /.example.com/, "" )
servers.each do |server|
if hostname == server then
puts "that's the one"
break
end
end
... when I execute this script I get this output ...
$ ./test.rb abc1
./test.rb:5: syntax error, unexpected ',', expecting ']'
, "xyz1-2-l"
^
./test.rb:6: syntax error, unexpected ',', expecting $end
, "dws-zxy-l"
^
... if I simply put everything on the same line its ok ...
$ cat test.rb
#!/usr/bin/ruby
servers = [ "xyz1-3-l" , "xyz1-2-l" , "dws-zxy-l" , "abcl" ]
hostname_input = ARGV[0]
hostname = hostname_input.gsub( /.example.com/, "" )
servers.each do |server|
if hostname == server then
puts "that's the one"
break
end
end
$ ./test.rb dws-zxy-l
that's the one
Look ma, no commas (or quotes):
servers = %W[
xyz1-3-l
xyz1-2-l
dws-zxy-l
abcl
]
# => ["xyz1-3-l", "xyz1-2-l", "dws-zxy-l", "abcl"]
Newlines are significant in Ruby. You need to put the comma at the end of the line or use a backslash before your newline to indicate that the line is continuing (of course, in that case, what's the point in moving the comma to the next line?).

Resources