I have the following as part of a class
def to_s
i = 0
first_line? = true
output = ''
#selections.each do | selection |
i += 1
if first_line?
output << selection.to_s(first_line?)
first_line? = false
else
output << selection.to_s
end
if i >= 5
output << "\r"
i = 0
else (output << " $ ")
end
end
return output
end
And i am getting the following syntax errors
SyntaxError: list2sel.rb:45: syntax error, unexpected '='
first_line? = true
^
list2sel.rb:47: syntax error, unexpected keyword_do_block, expecting keyword_end
#selections.each do | selection |
^
list2sel.rb:51: syntax error, unexpected '='
first_line? = false
^
What give, also thanks in advance, this is driving me nuts.
I suppose, you can't name variables with '?' at the end.
Variable names (with a few exceptions noted below) can only contain letters, numbers and the underscore. (Also, they must begin with a letter or the underscore; they can't begin with a number.) You can't use ? or ! in a variable name.
Beyond that rule, there is a strong convention in Ruby that a question mark at the end of something indicates a method that returns a boolean value:
4.nil? # => returns false....
So even if you could use it, a variable like first_line? would confuse (and then annoy) the hell out of Rubyists. They would expect it be a method testing whether something was the first line of something (whatever exactly that means in context).
Exceptions about variable names:
Global variables begin with $ - e.g., $stdin for standard input.
Instance variables begin with # - e.g. #name for an object
Class variables begin with ## - e.g. ##total for a class
I believe this is a more concise way of doing the above (untested):
def to_s
output = ""
#selections.each_with_index do | selection,line |
output << line==0 ? selection.to_s(true) and next : selection.to_s
output << line % 5 ? " $ " : "\r"
end
return output
end
If you are not a fan of the ternary operator (x ? y : z) then you can make them ifs:
def to_s
output = ""
#selections.each_with_index do | selection,line |
if line==0
output << selection.to_s(true)
else
output << selection.to_s
if line % 5
output << " $ "
else
output << "\r"
end
end
end
return output
end
Variable names allow non-ASCII letters, and there are non-ASCII versions of the question mark, so you can put question marks (and also some forms of space characters) into variable names.
Related
I'm trying to concatenate a constant into a string but I'm getting syntax error, unexpected unary+, expecting end' (SyntaxError)`
This is an example of what I have to do:
NAME = "Jane"
def a_function
s = 'Hi' + NAME +' !'
puts s
end
I know you can do "Hi #{NAME}!" but in my case the string has to be with single quotes.
How can I achieve this?
You are missing a space between + and ' !'.
This is a special case of confusing Ruby, because a single expression like +x is actually a valid unary expression meaning just x, the same way as +1 means 1.
Because of this it's likely Ruby is interpreting your expression a + b +c, as a + b c, which is invalid, and hence the error.
The fix:
s = 'Hi ' + NAME + ' !'
^------ Note the space here!
I am trying to create a do block with index. But I keep getting: syntax error, unexpected '|'
This is my code:
def same_char_collapse(str)
chars = str.split("")
while chars.each.with_index do | letter, i |
if letter[i] == letter[i + 1]
letter[i] = ""
letter[i +1] = ""
end
break
end
end
The error I am getting:
/tmp/file.rb:5: syntax error, unexpected '|'
...hile chars.each.with_index do | letter, i |
... ^
/tmp/file.rb:5: syntax error, unexpected '|', expecting '='
...ach.with_index do | letter, i |
... ^
What am I doing wrong?
This line doesn't make sense:
while chars.each.with_index do |letter, i|
I think you just meant to use:
chars.each.with_index do |letter, i|
A while loop, in any language, takes the form: while(conditional) ..... You don't have a conditional here, so it's not a valid use case for while.
On the other hand, methods such as each will:
Call the given block once for each element in self, passing that element as a parameter.
Note: You also could have used chars.each_with_index instead of .each.with_index.
I got this assignment in Codecademy. I want to print the even numbers.
print "Print any number:"
inpt = gets.chomp
def odd_or_even(num)
if num % 2 == 0
print "even"
else
print "odd"
end
end
I do not get any output. Is the problem in the method, or how I've written the equation? I've tried changing both.
You defined the method odd_or_even but never actually call it.
You have two options:
Take the more script-like approach and work with the input without the use of methods:
print 'Print any number: '
input = gets.to_i
# ^ convert the input (which is always a string) to an integer
if input % 2 == 0
puts 'even'
# ^ is the same as `print` but adds a newline character at the end
# (unless the string ends with a newline character)
else
puts 'odd'
end
If you want to use a method you'll have to define it and call it as well:
def odd_or_even(num)
if num % 2 == 0
puts 'even'
else
puts 'odd'
end
end
print 'Print any number: '
input = gets.to_i
odd_or_even(input)
# ^ method is called here
Ruby also has a lot of build-in helpers. You can achieve the same result with the following two lines:
print 'Print any number: '
puts gets.to_i.odd? ? 'odd' : 'even'
references:
#gets get user input
String#to_i convert input to an integer
Integer#odd? check if the integer is odd
Ternary if: use inline of if expression ? true : false
I think you have to check your input data.
Otherwise it may be a situation:
'abc'.to_i.even? #=> true
It's because non-digital String#to_i returns 0.
As you see it's not good.
def odd_or_even(number)
number.odd? ? 'odd' : 'even'
end
puts 'Print any number:'
input = gets.chomp
if input =~ /\D/
puts 'It is not a number'
else
puts "It's #{odd_or_even(input.to_i)}"
end
Firstly we validate data using regex. If it's not a number we will not check is it odd or even.
Note:
Very often we use =~ operator to match String and Regexp.
/\D/ means any non-digit character.
i = 20
loop do
i -= 1
next if i % 2 == 1
print "#{i}"
break if i <= 0
end
I see two issues with what you've posted - first gets.chomp is going to return a string and you really want an integer, so you'd want to do gets.to_i (or Integer(gets) if you want to guard against non-numeric inputs). The second is that print doesn't include a line break, so that could be the source of your "no output" issue - maybe try switching to puts instead?
This function is supposed to pull names from a Comma Separated Values file, and place them into an array.
def xprt_csv_to_ary(csv_file)
namecatcher_regex = "/^[\.{1}]([A-Z]+)\.{3}/" # Matches up to char before next name
current_word = 0
names_array = []
while current_word < 5000
if current_word == 0
name = csv_file.readline.match(namecatched_regex)
else
name = csv_file.past_match.match(namecatcher_regex)
end
names_array[current_word] = name
current_word ++
end
return names_array
end
I'm getting the following error:
syntax error, unexpected keyword_end
I would be as happy to be referred to an existing question that solves my problem as to have someone answer me directly.
Your error comes from line:
current_word ++
There's no such syntax in Ruby. It should be:
current_word += 1
What's more, you create your regexp incorrectly. It should be:
namecatcher_regex = /^[\.{1}]([A-Z]+)\.{3}/
There may be some other errors that I didn't notice.
On this line:
current_word ++
You are telling Ruby to add something to current_word, but you never tell it what to add, instead there's an end directly on the next line. You are missing the operand to the unary +. It should be something like
current_word + something_else
or
current_word + +something_else
In Ruby, whitespace is allowed around operators, so
a +
b
# equivalent to a + b, which is equivalent to a.+(b)
and even
+
a
# equivalent to +a, which is equivalent to a.+#()
is perfectly fine, so if you combine the two, you get that
a + +
b
# equivalent to a + +b, which is equivalent to a.+(b.+#())
is also perfectly fine, and since whitespace around operands is perfectly fine but optional,
a+b
and
a ++
b
# equivalent to a + +b as above
is also perfectly fine.
That's why you only get the error on the next line with the end, because only there can Ruby tell that you are missing the operand to the unary prefix + operator.
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