How to receive data from user without ruby adding an extra newline - ruby

I am trying to create a program that alphabetizes a users' word entries. However, inspection of the users entries reveals that ruby is for some reason adding a newline character to each word. For instance, If i enter Dog, Cat, Rabbit the program returns ["Cat\n", "Dog\n", "Rabbit\n"] How do i prevent this from happening?
words = []
puts "Enter a word: "
until (word = gets).to_s.chomp.empty?
puts "Enter a word: "
words << word
end
puts words.sort.inspect

Change your code to:
until (word = gets.chomp).empty?
The way you're doing it now:
(word = gets).to_s.chomp.empty?
gets the string from the keyboard input, but it isn't returned to your code until the user presses Return, which adds the new-line, or carriage-return + new-line on Windows.
to_s isn't necessary because you're already getting the value from the keyboard as a string.
chomp needs to be tied to gets if you want all the input devoid of the trailing new-line or new-line/carriage-return. That will work fine when testing for empty?.

Ruby 2.4 has a solution for this:
input = gets(chomp: true)
# "abc"

Related

How do I receive multiple paragraphs from a user in Ruby2.6.3?

I'm trying to receive multiple paragraphs at once from a user.
I've tried using gets, but it doesn't seem to be working... it discards the second paragraph:
#The code:
print("Paste your text here: ")
.. essay = gets
.. puts(essay)
# Getting user imput (the second sentance is a separate paragraph)
Paste your text here: I like cake.
It makes me happy.
# What the computer did for puts(essay):
I like cake.
=> nil
I expected the result to be something like this:
"I like cake.\nIt makes me happy.\n"
But it gave me "I like cake." instead.
How could I end up with my expected result?
Add paragraphs to a string until the input consists of a empty line:
str = ""
para = "init"
str << (para = gets) until para.chomp.empty? #or para == "\n"
p str
Here's an alternative, with a slightly different logic
def getps
save, $/ = $/, "\n\n"
gets.chomp
ensure
$/ = save
end
str = getps
The global variable $/ is what Ruby uses to find out what line end is. gets gets things till line end. If we tell Ruby that line end is two newlines, then gets waits till we have two newlines in a row till it exits. Since we don't need them, we'll just chomp them off. The rest of the code is just to ensure that $/ gets restored properly afterwards so normal gets is not messed up forever.

Ruby newline use of two \n

I have a question about the need for the use of \n\n to make a newline.
Please see below examples.
If I do ..
puts "hello"
puts "hi"
or
puts "hello\n"
puts "hi"
The output is..
hello
hi
If I do ..
puts "hello\n\n"
puts "hi"
The output is..
hello
hi
Why do I need \n\n to make one extra newline?
Why doesn't the single \n make any difference?
From the documentation:
puts(obj, ...) → nil
Writes the given objects to ios as with IO#print. Writes a record separator (typically a newline) after any that do not already end with a newline sequence. If called with an array argument, writes each element on a new line. If called without arguments, outputs a single record separator.
The purpose of puts is to ensure the string ends with the newline character.
If there is none, then one newline character will be appended.
If there is one or more, no newline character will be appended.
The other answers here nailed it.
If you want to avoid the magic handling of \n, try using print instead of puts. print outputs your string literally, with no line ending unless you put it there.
> 3.times { print 'Zap' }
ZapZapZap=> 3
> 3.times { puts 'Zap' }
Zap
Zap
Zap
=> 3

How to use "gets" and "gets.chomp" in Ruby

I learned that gets creates a new line and asks the user to input something, and gets.chomp does the same thing except that it does not create a new line. gets must return an object, so you can call a method on it, right? If so, lets name that object returned by gets as tmp, then you can call the chomp method of tmp. But before gets returns tmp, it should print a new line on the screen. So what does chomp do? Does it remove the new line after the gets created it?
Another way to re-expound my question is: Are the following actions performed when I call gets.chomp?
gets prints a new line
gets returns tmp
tmp.chomp removes the new line
User input
Is this the right order?
gets lets the user input a line and returns it as a value to your program. This value includes the trailing line break. If you then call chomp on that value, this line break is cut off. So no, what you have there is incorrect, it should rather be:
gets gets a line of text, including a line break at the end.
This is the user input
gets returns that line of text as a string value.
Calling chomp on that value removes the line break
The fact that you see the line of text on the screen is only because you entered it there in the first place. gets does not magically suppress output of things you entered.
The question shouldn't be "Is this the right order?" but more "is this is the right way of approaching this?"
Consider this, which is more or less what you want to achieve:
You assign a variable called tmp the return value of gets, which is a String.
Then you call String's chomp method on that object and you can see that chomp removed the trailing new-line.
Actually what chomp does, is remove the Enter character ("\n") at the end of your string. When you type h e l l o, one character at a time, and then press Enter gets takes all the letters and the Enter key's new-line character ("\n").
1. tmp = gets
hello
=>"hello\n"
2. tmp.chomp
"hello"
gets is your user's input. Also, it's good to know that *gets means "get string" and puts means "put string". That means these methods are dealing with Strings only.
chomp is the method to remove trailing new line character i.e. '\n' from the the string.
whenever "gets" is use to take i/p from user it appends new line character i.e.'\n' in the end of the string.So to remove '\n' from the string 'chomp' is used.
str = "Hello ruby\n"
str = str.chomp
puts str
o/p
"Hello ruby"
chomp returns a new String with the given record separator removed from the end of str (if present).
See the Ruby String API for more information.
"gets" allows user input but a new line will be added after the string (string means text or a sequence of characters)
"gets.chomp" allows user input as well just like "gets", but there is
not going to be a new line that is added after the string.
Proof that there are differences between them:
Gets.chomp
puts "Enter first text:"
text1 = gets.chomp
puts "Enter second text:"
text2 = gets.chomp
puts text1 + text2
Gets:
puts "Enter first text:"
text1 = gets
puts "Enter second text:"
text2 = gets
puts text1 + text2
Copy paste the code I gave you, run and you will see and know that they are both different.
For example:
x = gets
y = gets
puts x+y
and
x = gets.chomp
y = gets.chomp
puts x+y
Now run the two examples separately and see the difference.

Ruby redaction program logic?

Okay,
I am doing the codeacademy ruby track and I am not stock with the problem.
I can make it works now, but I don't understand why it works.
instructions for exercise:
Let's start simple: write an .each loop that goes through words and just prints out each word it finds.
I have broken the problem into steps to try to understand why it works
but I am very confused.
My code for the problem is:
puts "Text to search through: " #ask user for input
text = gets.chomp
#store the user's input into the variable text
puts "Text to be reducted: "
#ask the user for input
redact = gets.chomp
#store the user's input into the variable redact
words = text.split(" ")
=begin
split the user's input into the variable words
store that input into the variable words
=end
words.each do |word|
=begin
creates a placeholder for the user's input
then attach an expression to the input stored in
the variable words one at a time. The variable
words holds the value of the variable text
=end
if word != redact
=begin
if word (which now holds the value of words that's
stored in the variable text, and which is the user's input)
is not equal to the value of the variable redact do something
=end
word = word + " "
=begin
increment the value of word by an empty space
why do I need to increment the value of word by an empty space?
=end
print "#{word}" #print the value of the variable word
else
print "REDACTED" #otherwise, print the value redacted
end
end
The program works if I use a string separated by an space and only if I change
word = word + ""
instead of
word = word + " "
I would truly appreciate if someone break it down for me, step by step.
I created a video of it for a more visual explanation of it.
here is the link: ruby redaction video
thank you.
The problem in your video is that "nelson" is not the same as "nelson ", and the Codeacademy scoring doesn't see a match when you append a space to the word before printing it.
I am reading this problem in July 2019..
So anybody who is reading this problem and getting confused with the below part asked by the user:
word = word + " "
=begin
increment the value of word by an empty space
why do I need to increment the value of word by an empty space?
So the answer is that the + sign is not for incrementing the value it's for adding a space and the + sign is used as string concatenator. So it has been placed there so that whatever words are being searched and displayed, they have a space between them.

How to look for a specific character in an array in Ruby

I'm trying to look for a specific character in an array but this character is being entered by the user.
I first order the array and then ask the user to enter a specific character and then I should see if that character exists in any of the words that the array has
For some reason, if when checking for the existence of the character, I "hard code" a character, it works, but it doesn't work if I try to look for the character that the user has entered...
list = [ 'Mom' , 'Dad' , 'Brother' , 'Sister' ]
puts ("Enter the character you would like to find");
character = gets
for i in 0..(list.length - 1)
if (list[i].include?(#{character}))
puts ("Character #{character} found in the word #{list[i]}");
end
Thanks a lot!
It is because gets adds a \n to the end of the string. Use gets.chomp! so you can get rid of the last char.
You should use "chomp" to get rid of the carriage return at the end of the line of the input. In addition you could condense your code as well.
list = [ 'Mom' , 'Dad' , 'Brother' , 'Sister' ]
puts ("Enter the character you would like to find");
character = gets.chomp
list.each do |e|
puts "Character #{character} found in the word #{e}" if e.include?(character)
end

Resources