Why strings are not coming in same line in ruby - ruby

In this code in three places i am having puts, Where first one prints variables in different line with the string and second one too. but 3rd one gives in same line.
def calliee (name,game)
#puts("#{name}#{game} he might be a bad guy")
return " he might be a bad guy #{name}#{game}"
end
def mymethod(name)
puts("enter your last name")
ss=gets()
#return "#{name}"+"#{ss}"+"he might be a bad guy"
calliee(name,ss)
end
puts("enter tour first name")
tt=gets()
#ww=mymethod(tt)
yy=mymethod(tt)
puts(yy)
puts("#{tt} is 1st name")
puts("prabhu "+"#{2+3}"+"#{4+5}")
i want everything in same line and i need to know why this is happening. please help

Kernel#gets gives you a string with the \n added to the end of the string. That causing the output in the multiple lines.
To make your output as you wanted it to be, you need to use #chomp method, like gets.chomp.

Adding to Arup's answer:
puts adds a newline to the end of the output. print does not. So you may also want to replace puts with print to have all output in one line.

Related

How could I display a text on the same line?

I accept text input from a user. When I use the received text within a line as follows,
puts "whats your name?"
$name = STDIN.gets
puts "Oh #$name, nice to meet you"
it is displayed on a separate line. It puts the name and then the "nice to meet you" on a new line.
Is there a way to fix this? Also if you see something wrong, please tell me.
The method gets without any option receives the input including the terminating end of line. If you simply interpolate that as a part of a string, that end of line will be printed as a line break.
To avoid line break, pass the parameter chomp with value true to gets:
$name = STDIN.gets(chomp: true)
In the old school way, apply chomp after gets like:
$name = STDIN.gets.chomp
chomp removes white space characters from the end of the string, thus it avoids the line break.
Other things wrong about your code are:
You missed to capitalize the sentence whats your name?.
You missed an apostrophe in whats.
You should avoid using a global variable like $name. Try using another type of variable.
You missed a period at the end of the sentence Oh #$name, nice to meet you.
I would suggest changing that global variable to a local variable. If you do, you'll have to change the way you interpolate.
Also, I would suggest using the gets.chomp method and leave out STDIN.
Example:
puts "What's your name?"
name = gets.chomp
puts "Oh, #{name}, nice to meet you."
gets is used to input data from the user and includes a line break at the end.
chomp is used to return and store data as a string value.
$name = STDIN.gets.chomp

Difference between ways to use gets method

I saw two ways to use gets, a simple form:
print 'Insert your name: '
name = gets()
puts "Your name is #{name}"
and a form that drew my attention:
print 'Insert your name: '
STDOUT.flush
name = gets.chomp
puts "Your name is #{name}"
The second sample looks like perl in using the flush method of the default output stream. Perl makes explicit default output stream manipulating; the method flush is a mystery to me. It can behave different from what I'm inferring, and it uses chomp to remove the new line character.
What happens behind the scenes in the second form? What situation is it useful or necessary to use the second form?
"Flushing" the output ensures that it shows the printed message before it waits for your input; this may be just someone being certain unnecessarily, or it may be that on certain operating systems you need it. Alternatively you can use STDOUT.sync = true to force a flush after every output. (You may wonder, "Why wouldn't I always use this?" Well, if your code is outputting a lot of content, repeatedly flushing it may slow it down.)
chomp removes the newline from the end of the input. If you want the newline (the result of the user pressing "Enter" after typing their name) then don't chomp it.
Looking at some Github code I can see that STDOUT.flush is used mostly for server-side/multi-threaded jobs, and not in everyday use.
Generally speaking, when you want to accept input from the user, you'd want to use gets.chomp. Just remember, no matter what the user enters, Ruby will ALWAYS interprete that as a string.
To convert it to an integer, you need to call to_i, or to_f for a float. You don't need chomp in these cases, since to_i or to_f removes the "\n" automatically. There are a lot of subtle things going on implicitly as you'll see, and figuring them out is simply a matter of practice.
I've rarely seen someone use STDOUT.flush except in mutli-threading. Also it makes things confusing, defeating the whole purpose of writing elegant code.

Ruby puts<<PARAGRAPH

puts <<PARAGRAPH
There's somthing going on here.
With the PARAGRAPH thing
We'll be able to type as much as we like.
Even 4 lines if we want, or 5, or 6 .
PARAGRAPH
This can work, using Notepad++
But why this can't work?
puts <<PARAGRAPH
aaaa Aa
aaa
AA
PARAGRAPH
test.rb:1: syntax error,unexpected tCONSTANT, expecting $end
Thanks!
My guess is that in your second snippet PARAGRAPH is not at the begging of the line.
The multi-line strings in ruby, are weird that way. The terminating character (whatever it may be) must be the first thing on a line to terminate the string, otherwise you will often see the syntax errors.
Ensure ensure that PARAGRAPH (the second instance) is a) spelled the same as your first instance, and b) at the start of the line, or change your code to:
def go
puts <<-PARAGRAPH # hyphen allows the end marker to be indented
Hi mom!
PARAGRAPH
end
For more information, read the intro to Strings and the full description.
The code works for me. One way I broke it was by adding space between << and PARAGRAPH
puts << PARAGRAPH
PARAGRAPH
This is different from the next example.
puts <<PARAGRAPH
PARAGRAPH
Edit: As I continue play with it I found that PARAGRAPH is just like any place holder. You can do the following and you will still get a paragraph in a string
puts <<ANYTHING_YOU_WANT
ANYTHING_YOU_WANT
I thought it was cool that it is not restricted only to the word PARAGRAPH. I didn't know.
I can get either version to error by adding additional spaces after the final PARAGRAPH.
Ensure that the closing PARAGRAPH is truly on a new line (per diedthreetimes' answer) and has no trailing characters (i.e. spaces, tabs, etc.)

Delete first two lines of file with ruby

My script reads in large text files and grabs the first page with a regex. I need to remove the first two lines of each first page or change the regex to match 1 line after the ==Page 1== string. I include the entire script here because I've been asked to in past questions and because I'm new to ruby and don't always know how integrate snippets as answers:
#!/usr/bin/env ruby -wKU
require 'fileutils'
source = File.open('list.txt')
source.readlines.each do |line|
line.strip!
if File.exists? line
file = File.open(line)
end
text = (File.read(line))
match = text.match(/==Page 1(.*)==Page 2==/m)
puts match
end
Now, when You have updated your question, I had to delete a big part of so good answer :-)
I guess the main point of your problem was that you wanted to use match[1] instead of match. The object returned by Regexp.match method (MatchData) can be treated like an array, which holds the whole matched string as the first element, and each subquery in the following elements. So, in your case the variable match (and match[0]) is the whole matched string (together with '==Page..==' marks), but you wanted just the first subexpression which is hidden in match[1].
Now about other, minor problems I sense in your code. Please, don't be offended in case you already know what I say, but maybe others will profit from the warnings.
The first part of your code (if File.exists? line) was checking whether the file exists, but your code just opened the file (without closing it!) and still was trying to open the file few lines later.
You may use this line instead:
next unless File.exists? line
The second thing is that the program should be prepared to handle the situation when the file has no page marks, so it does not match the pattern. (The variable match would then be nil)
The third suggestion is that a little more complicated pattern might be used. The current one (/==Page 1==(.*)==Page 2==/m) would return the page content with the End-Of-Line mark as the first character. If you use this pattern:
/==Page 1==\s*\n(.*)==Page 2==/m
then the subexpression will not contain the white spaces placed in the same line as the '==Page 1==` text. And if you use this pattern:
/==Page 1==\s*\n(.*\n)==Page 2==/m
then you will be sure that the '==Page 2==' mark starts from the beginning of the line.
And the fourth issue is that very often programmers (sometimes including me, of course) tend to forget about closing the file after they opened it. In your case you have opened the 'source' file, but in the code there was no source.close statement after the loop. The most secure way of handling files is by passing a block to the File.open method, so You might use the following form of the first lines of your program:
File.open('list.txt') do |source|
source.readlines.each do |line|
...but in this case it would be cleaner to write just:
File.readlines('list.txt').each do |line|
Taking it all together, the code might look like this (I changed the variable line to fname for better code readability):
#!/usr/bin/env ruby -wKU
require 'fileutils'
File.readlines('list.txt').each do |fname|
fname.strip!
next unless File.exists? fname
text = File.read(fname)
if match = text.match(/==Page 1==\s*\n(.*\n)==Page 2==/m)
# The whole 'page' (String):
puts match[1].inspect
# The 'page' without the first two lines:
# (in case you really wanted to delete lines):
puts match[1].split("\n")[2..-1].inspect
else
# What to do if the file does not match the pattern?
raise "The file #{fname} does NOT include the page separators."
end
end

Why does Ruby's 'gets' includes the closing newline?

I never need the ending newline I get from gets. Half of the time I forget to chomp it and it is a pain in the....
Why is it there?
Like puts (which sounds similar), it is designed to work with lines, using the \n character.
gets takes an optional argument that is used for "splitting" the input (or "just reading till it arrives). It defaults to the special global variable $/, which contains a \n by default.
gets is a pretty generic method for readings streams and includes this separator. If it would not do it, parts of the stream content would be lost.
var = gets.chomp
This puts it all on one line for you.
If you look at the documentation of IO#gets, you'll notice that the method takes an optional parameter sep which defaults to $/ (the input record separator). You can decide to split input on other things than newlines, e.g. paragraphs ("a zero-length separator reads the input a paragraph at a time (two successive newlines in the input separate paragraphs)"):
>> gets('')
dsfasdf
fasfds
dsafadsf #=> "dsfasdf\nfasfds\n\n"
From a performance perspective, the better question would be "why should I get rid of it?". It's not a big cost, but under the hood you have to pay to chomp the string being returned. While you may never have had a case where you need it, you've surely had plenty of cases where you don't care -- gets s; puts stuff() if s =~ /y/i, etc. In those cases, you'll see a (tiny, tiny) performance improvement by not chomping.
How I auto-detect line endings:
# file open in binary mode
line_ending = 13.chr + 10.chr
check = file.read(1000)
case check
when /\r\n/
# already set
when /\n/
line_ending = 10.chr
when /\r/
line_ending = 13.chr
end
file.rewind
while !file.eof?
line = file.gets(line_ending).chomp
...
end

Resources