How to stop program from exiting itself out? - ruby

my question regards the programming language of Ruby and the Ruby program.
After using this code:
print "What's your first name?"
first_name = gets.chomp
first_name.capitalize!
print "What's your last name?"
last_name = gets.chomp
last_name.capitalize!
print "What city are you from?"
city = gets.chomp
city.capitalize!
print "What state or province are you from?"
state = gets.chomp
state.upcase!
print "Your name is #{first_name} #{last_name} and you're from #{city}, #{state}!"
After the program asks for the state or province and I enter in a value, the program automatically exits itself out.
I am using RubyInstaller for Windows (version Ruby 1.9.3-p545).
I used Notepad++ to type the code and saved it under the Ruby .rb extension.
I ran the program by double-clicking the file from where I saved it.
Thanks! :)

One easy way is to add this at the end:
puts "Press RETURN when you're done."
gets

Well, it is the end of the program, there are no more user questions to be answered at that point. So what do you want your program to do after it asks you for state/province and repeats your data to you?
You might want to change print to puts though.
EDIT: As Michael and Leo say in comments, if you start your program by double-clicking the file in Windows, it will open a terminal, run your program, and close the terminal as soon as the program is done. The program is repeating the information back in a sentence with the valoues in the sentence; but that information is on your screen only for a split second, before Windows closes your program's terminal. Leo and Michael each suggest a way (run from terminal or insert a sleep statement); another way similar to Leo's is having another gets at the end and asking the user to hit Enter when they are done reading.

have you tried from your command to run
irb code.rb
Assuming your file name is code.rb
Also as suggests try puts instead of print

Infinite loop still works
while true
'something'
end

print"What's your first name?"
first_name=gets.chomp
first_name.capitalize!
print"What's your last name?"
last_name=gets.chomp
last_name.capitalize!
print"What city are you from?"
city=gets.chomp
city.capitalize!
print"What state are you from?"
state=gets.chomp
state.upcase!
puts"Your name is #{first_name},your last name is #{last_name}, and your from #{city},#{state}!"
Works

Related

Gets stops processing script if it encounters a apostrophe

I'm futzing with a lesson over on Codecademy, pretty basic but the lesson prompts the user for a string and then prompts them for words to hide from the string. I've already finished with the lesson but I wanted to try messing with it outside of the lesson.
What I'm finding is the following script will run to completion in the lesson's scripting and interpreter area but if I try to run the same script over at say labs.codecademy.com or repl.it
I'll get prompted for the first question and if I enter a string containing an apostrophe it won't go on to the next prompt. I'm not getting an error, but eventually I'll get a "This program is taking too long to finish" pop up.
Here's the script:
puts "Tell me something."
text = gets.chomp
puts "What would you like me to forget?"
redact = gets.chomp
words = text.split(" ")
words.each { |text|
if redact.include? text
print "REDACTED "
else
print text + " "
end
}
So for example if you were to enter I really like blueberry pie that passes, but if you were to enter They've told me I should try the blueberry pie the program gets hung up.
I'm a complete novice when it comes to Ruby, but is there a way to have gets process that sort of punctuation? Or is that not the right way to go about it? Or is it just the environment I'm trying to run this program in?
IO.gets is a system-level call: http://apidock.com/ruby/IO/gets
it well read from STDIN (standard input) which is the text that you type in a terminal window: http://en.wikipedia.org/wiki/Standard_streams
browsers per-se don't have this and it might depend on the implementation of the web-based console about how they handle calls like that. usually, there are known limitations (like this one).
as #BroiStatse pointed out, it might as well be a bug in in their browser-based implementation.

Why does gets return zero in Ruby

I have a simple method
def save_logline
print "What's the name of the movie"
movie_name = gets.strip
print "And what is your precious logline?"
logline = gets.strip
File::open(movie_name + '.txt', 'w') do |f|
f.write(logline)
end
end
Anytime I run the code, I receive the first prompt where I insert the name of the movie, but once I press enter the second print is called, giving me this message.
And what is your precious logline?=> 0
The file is written but I'm prevented from inserting anything into the text file. What's wrong with my logic and how do I fix this? I am using irb in RubyMine with Ubuntu.
EDIT: It appears that due to other users response to my code working and my own test on a different development machine my code is just not working on that one machine. The only thing I could say is that I was using RubyMine's irb console. The question now must be is it a RubyMine issue or is there a bigger problem with my dev machine?
FINAL EDIT: I checked on my second comp that has RubyMine, it appears that it does not work in that RubyMine's irb console either. I'm going to issue the bug to RubyMine and give credit to Jeremy in a day or two unless someone knows why RubyMine's irb is acting funky.
Your code works. The 0 is the return value of f.write. It's saying it wrote zero bytes to your file, because you didn't give it any input.
Edit: Maybe you pressed enter twice by accident...

Using Ruby ask for value, store value in variable (x), read input file line by line, replace y with x, output file

I'm pretty new to scripting in general so I'm still learning a lot in my quest to learn ruby.
I'm not sure how clear my title is so I'll show you what I've started with.
puts "Enter the hostname in the format [SID-Profile] -->"
var1 = gets
puts "Enter the IP address and Mask in the format [1.2.3.4 255.255.255.0] -->"
var2 = gets
This is where my efforts fall apart and I'm starting to wonder if I've even approached the problem in a very practical way.
I would like to ask a series of questions, hold the answers to the questions in variables, then import a file, read it line by line finding #HOSTNAME in the file and replacing it with the value being held in var1. Once the entire file has been searched and all instances of #HOSTNAME have been replace with var1, start again for var2. This seemed like it would be quick when I first thought of it, but I'm stuck.
Any ideas? If there are other approaches I'd love to hear those too.
There isn't really a way to do a replace in a file using ruby, but you can cheat a little.
I'd do both substitutions at the same time, so that you don't have to read the file twice.
Try this
data = IO.readlines("filename")
puts "Enter Hostname"
hostname = gets.chomp
puts "Enter IP"
ip = gets.chomp
data.each do |line|
line.gsub("#HOSTNAME",hostname)
line.gsub!("#IPADDRESS",ip)
puts line
end
This will read the file and print it to the screen, so that you can see and verify the output.
You can then direct the output of the script to a new file, and finally move the new file into the place of the old one.

Multi-line input problems when using STDIN.gets

Having looked at this question, I have the following code:
$/ = "\0"
answer = STDIN.gets
Now, I was hoping that this would allow the user to:
enter a multi-line input, terminating by pressing Ctrl-D.
enter a single line input, terminating by pressing Ctrl-D.
enter a "nothing" input, terminating by pressing Ctrl-D.
However, the behaviour I actually see is that:
The user can enter a multi-line input fine.
The user can not enter a single line input, unless they hit Ctrl-D twice.
The user can enter a "nothing" input if they hit Ctrl-D straight away.
So, why does the single line situation (i.e. if the user has entered some text but no newline and then hit Ctrl-D) require two presses of Ctrl-D? And why does it work then if the user enters nothing? (I have noted that if they enter nothing and hit Ctrl-D, I don't get an empty string but the nil class - I discovered this when trying to call .empty? on the result, since it suddenly failed horribly. If there is a way to get it to return an empty string as well, that would be nice. I prefer checking .empty? to ==, and don't particularly want to define .empty? for the nil class.)
EDIT: Since I really would like to know the "correct way" to do this in Ruby, I am offering a bounty of 200 rep. I will also accept answers that give another way of entering terminal multi-line input with a sensible "submit" procedure - I will be the judge of 'suitable'. For example, we're currently using two "\n"s, but that's not suitable, as it blocks paragraphs and is unintuitive.
The basic problem is the terminal itself. See many of the related links to the right of your post. To get around this you need to put the terminal in a raw state. The following worked for me on a Solaris machine:
#!/usr/bin/env ruby
# store the old stty settings
old_stty = `stty -g`
# Set up the terminal in non-canonical mode input processing
# This causes the terminal to process one character at a time
system "stty -icanon min 1 time 0 -isig"
answer = ""
while true
char = STDIN.getc
break if char == ?\C-d # break on Ctrl-d
answer += char.chr
end
system "stty #{old_stty}" # restore stty settings
answer
I'm not sure if the storing and restoring of the stty settings is necessary but I've seen other people do it.
When reading STDIN from a terminal device you are working in a slightly different mode to reading STDIN from a file or a pipe.
When reading from a tty Control-D (EOF) only really sends EOF if the input buffer is empty. If it is not empty it returns data to the read system call but does not send EOF.
The solution is to use some lower level IO and read a character at a time. The following code (or somethings similar) will do what you want
#!/usr/bin/env ruby
answer = ""
while true
begin
input = STDIN.sysread(1)
answer += input
rescue EOFError
break
end
end
puts "|#{answer.class}|#{answer}|"
The results of running this code with various inputs are as follows :-
INPUT This is a line<CR><Ctrl-D>
|String|This is a line
|
INPUT This is a line<Ctrl-D>
|String|This is a line|
INPUT<Ctrl-D>
|String||

Ruby Program Error: NoMethodError

I typed up a simple Ruby code for a tutorial question, as shown below.
#Grandma is deaf!
puts "Hey Sonny! It's your lovely Grandmother! How are you?"
response = gets.chomp
while response != "BYE"
if response != response.upcase
puts "Huh?! I CAN'T HEAR YOU!"
else
puts "NO! NOT SINCE " + (1930 + rand(21)).to_s + "!"
end
response = gets.chomp
end
puts "GOOD BYE, SONNY!"
However, when I run this, the window displays:
Hey Sonny! It's your lovely Grandmother! How are you?
NoMethodError: private method ‘chomp’ called for nil:NilClass
at top level in deafGrandma.rb at line 3
I don't understand why chomp is not recognized. I'm using textMate on a Mac I have Ruby version 1.8.7, which should be fine. Any solutions?
Thank you so much :)
Adrian is right about interactive input being disabled in TextMate 1.5.9 (r1510). See this post from TextMate's developer.
However, you can upgrade to a "cutting-edge" TextMate release that restores interactive input, and will allow you to run the above code just fine. Go to TextMate's Preferences -> Software Updates and make sure Automatically check for updates is checked.
Select Cutting-Edge in the Watch For: dropdown menu. Finally, click Check Now. The latest release (r1589) should automatically download. Interactive input is re-enabled in this release.
If you are using the Cmd-R shortcut in TextMate to run your code, you will not be able to supply it input because textmate only supports output. You will have to run it in a terminal instead. The reason you are getting that error is because $stdin is closed, so gets returns nil.

Resources