Ruby newline use of two \n - ruby

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

Related

How can I print a string contained in an object as literal with Ruby?

I'm trying to write a program which will detect if a file has \n or \r\n line endings and then fix them. I'm hoping to have the script output some messages to a console, but I'm running into trouble. I can't figure out how to print the line endings as literals.
Here is my method which checks for the line ending type:
def determine_line_ending(filename)
File.open(filename, 'r') do |file|
return file.readline[/\r?\n$/]
end
end
ending = determine_line_ending(ARGV.first)
Supposedly this method will return either \n or \r\n if it matches one of those patterns on the first line of the file.
I would like to then print to the console which ending type was detected but if I use puts ending then it just adds a line ending to the console. I know that if I used puts '\r\n' then it will print them literal, or if I use double quotes I just have to escape the backslashes. But I'm pretty new to Ruby and I'm having a hard time just finding a way to print my variable as a literal instead of a string.
If I'm understanding you well, you want to print the "\r" string if the line ending is \r and "\r\n" if \r\n.
In this case you can use the dump function is what you need:
puts ending.dump // => "\r" or "\r\n"
I would use method String#inspect:
s = "abc\n\rdef"
puts s
puts s.inspect
This is very handy method that is defined on all objects. You can print hashes, arrays, whatever.

Comparing String with String from file in Ruby

data = File.read("data.txt")
if(data.to_s.eql? "hello")
...
end
My data.txt is filled with "hello" as well, so the if-loop should get active but it doesn't. What do I do wrong?
When reading data from a file, it's likely you get a newline tagged on to the end of your data.
For example, if I run the following in the terminal to create a file containing only the word 'hello':
echo hello > data.txt
And the read this in the terminal, I see:
cat data.txt
# => hello
However, jumping into irb, I get the following:
File.read("data.txt")
# => "hello\n"
The \n is the newline operator.
To solve your question, you can use:
if data.chomp == "hello"
...
end
chomp removes any record separator from the end of the string, giving you the comparison you're after.
If you just want to know whether the file contains the specified string, you can also use:
data['hello']
This will return the truthy value in the square brackets if present, or nil if not.
if data["hello"]
...
end

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

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"

How do I remove carriage returns with Ruby?

I thought this code would work, but the regular expression doesn't ever match the \r\n. I have viewed the data I am reading in a hex editor and verified there really is a hex D and hex A pattern in the file.
I have also tried the regular expressions /\xD\xA/m and /\x0D\x0A/m but they also didn't match.
This is my code right now:
lines2 = lines.gsub( /\r\n/m, "\n" )
if ( lines == lines2 )
print "still the same\n"
else
print "made the change\n"
end
In addition to alternatives, it would be nice to know what I'm doing wrong (to facilitate some learning on my part). :)
Use String#strip
Returns a copy of str with leading and trailing whitespace removed.
e.g
" hello ".strip #=> "hello"
"\tgoodbye\r\n".strip #=> "goodbye"
Using gsub
string = string.gsub(/\r/," ")
string = string.gsub(/\n/," ")
Generally when I deal with stripping \r or \n, I'll look for both by doing something like
lines.gsub(/\r\n?/, "\n");
I've found that depending on how the data was saved (the OS used, editor used, Jupiter's relation to Io at the time) there may or may not be the newline after the carriage return. It does seem weird that you see both characters in hex mode. Hope this helps.
If you are using Rails, there is a squish method
"\tgoodbye\r\n".squish => "goodbye"
"\tgood \t\r\nbye\r\n".squish => "good bye"
What do you get when you do puts lines? That will give you a clue.
By default File.open opens the file in text mode, so your \r\n characters will be automatically converted to \n. Maybe that's the reason lines are always equal to lines2. To prevent Ruby from parsing the line ends use the rb mode:
C:\> copy con lala.txt
a
file
with
many
lines
^Z
C:\> irb
irb(main):001:0> text = File.open('lala.txt').read
=> "a\nfile\nwith\nmany\nlines\n"
irb(main):002:0> bin = File.open('lala.txt', 'rb').read
=> "a\r\nfile\r\nwith\r\nmany\r\nlines\r\n"
irb(main):003:0>
But from your question and code I see you simply need to open the file with the default modifier. You don't need any conversion and may use the shorter File.read.
modified_string = string.gsub(/\s+/, ' ').strip
lines2 = lines.split.join("\n")
"still the same\n".chomp
or
"still the same\n".chomp!
http://www.ruby-doc.org/core-1.9.3/String.html#method-i-chomp
How about the following?
irb(main):003:0> my_string = "Some text with a carriage return \r"
=> "Some text with a carriage return \r"
irb(main):004:0> my_string.gsub(/\r/,"")
=> "Some text with a carriage return "
irb(main):005:0>
Or...
irb(main):007:0> my_string = "Some text with a carriage return \r\n"
=> "Some text with a carriage return \r\n"
irb(main):008:0> my_string.gsub(/\r\n/,"\n")
=> "Some text with a carriage return \n"
irb(main):009:0>
I think your regex is almost complete - here's what I would do:
lines2 = lines.gsub(/[\r\n]+/m, "\n")
In the above, I've put \r and \n into a class (that way it doesn't matter in which order they might appear) and added the "+" qualifier (so that "\r\n\r\n\r\n" would also match once, and the whole thing replaced with "\n")
Just another variant:
lines.delete(" \n")
Why not read the file in text mode, rather than binary mode?
lines.map(&:strip).join(" ")
You can use this :
my_string.strip.gsub(/\s+/, ' ')
def dos2unix(input)
input.each_byte.map { |c| c.chr unless c == 13 }.join
end
remove_all_the_carriage_returns = dos2unix(some_blob)

How do you loop through a multiline string in Ruby?

Pretty simple question from a first-time Ruby programmer.
How do you loop through a slab of text in Ruby? Everytime a newline is met, I want to re-start the inner-loop.
def parse(input)
...
end
String#each_line
str.each_line do |line|
#do something with line
end
What Iraimbilanja said.
Or you could split the string at new lines:
str.split(/\r?\n|\r/).each { |line| … }
Beware that each_line keeps the line feed chars, while split eats them.
Note the regex I used here will take care of all three line ending formats. String#each_line separates lines by the optional argument sep_string, which defaults to $/, which itself defaults to "\n" simply.
Lastly, if you want to do more complex string parsing, check out the built-in StringScanner class.
You can also do with with any pattern:
str.scan(/\w+/) do |w|
#do something
end
str.each_line.chomp do |line|
# do something with a clean line without line feed characters
end
I think this should take care of the newlines.

Resources