Why does gets return zero in Ruby - 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...

Related

What is wrong with this piece of code(trivial)

This is a very trivial function I wrote to read text as a prompt. It doesn't work but doesn't give me errors either. I've tried all modifications I can think if to get it to work, but to no avail.
Code:
def prompt(query="")
print (query) #I also tried 'print"#{query}"
var = gets()
return var
end
name = prompt("Input your name:")
puts"#{name}"
Nothing happens. This has frustrated me, that I couldn't do something so simple, and I've spent hour on it.
There was no problem with the code itself. It was simply that my editor Sublime Text 3 didn't handle accepting user input well.
How to make scripts run from command line:
Create a file ending in ".rb", for example "my_script.rb"
Run ruby my_script.rb
Don't forget ".rb" ;)

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.

What is the best way to get keyboard events (input without press 'enter') in a Ruby console application?

I've been looking for this answer in the internet for a while and have found other people asking the same thing, even here. So this post will be a presentation of my case and a response to the "solutions" that I have found.
I am such new in Ruby, but for learning purposes I decided to create a gem, here.
I am trying to implement a keyboard navigation to this program, that will allow the user use short-cuts to select what kind of request he want to see. And in the future, arrow navigations, etc.
My problem: I can't find a consistent way to get the keyboard events from the user's console with Ruby.
Solutions that I have tried:
Highline gem: Seems do not support this feature anymore. Anyway it uses the STDIN, keep reading.
STDIN.getch: I need to run it in a parallel loop, because at the same time that the user can use a short-cut, more data can be created and the program needs to show it. And well, I display formated text in the console, (Rails log). When this loop is running, my text lost the all the format.
Curses: Cool but I need to set position(x,y) to display my text every time? It will get confusing.
Here is where I am trying to do it.
You may note that I am using "stty -raw echo" (turns raw off) before show my text and "stty raw -echo" (turns raw on) after. That keeps my text formated.
But my key listener loop is not working. I mean, It works in sometimes but is not consistent. If a press a key twice it don't work anymore and sometimes it stops alone too.
Let me put one part of the code here:
def run
# Two loops run in parallel using Threads.
# stream_log loops like a normal stream in the file, but it also parser the text.
# break it into requests and store in #requests_queue.
# stream_parsed_log stream inside the #requests_queue and shows it in the screen.
#requests_queue = Queue.new
#all_requests = Array.new
# It's not working yet.
Thread.new { listen_keyboard }
Thread.new { stream_log }
stream_parsed_log
end
def listen_keyboard
# not finished
loop do
char = STDIN.getch
case char
when 'q'
puts "Exiting."
exit
when 'a'
#types_to_show = ['GET', 'POST', 'PUT', 'DELETE', 'ASSET']
requests_to_show = filter_to_show(#all_requests)
command = true
when 'p'
#types_to_show = ['POST']
requests_to_show = filter_to_show(#all_requests)
command = true
end
clear_screen if command
#requests_queue += requests_to_show if command
command = false
end
end
I need a light in my path, what should I do?
That one was my mistake.
It's just a logic error in another part of code that was running in another thread so the ruby don't shows the error by default. I used ruby -d and realized what was wrong. This mistake was messing my keyboard input.
So now it's fixed and I am using STDIN.getch with no problem.
I just turn the raw mode off before show any string. And everything is ok.
You can check here, or in the gem itself.
That's it.

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.

How can I programatically call the ruby debugger from within a ruby program in Ruby 1.9?

I am writing a web based debugger for Ruby, but in order to do this I need to be able to call the Ruby debugger from within a Ruby program on the server side. Has this ever been done? Is this even possible?
The end product being built will allow Ruby code to be edited, executed and stepped through using just a web browser. The ruby code that is to be debugged will be "eval"ed on the server side.
I have since been pointed in the right direction by one of the stackoverflow users who has suggested using popen or expect. I have tried both of these now but have encountered the following problems:
popen: When waiting for the console you have to use a timeout block to signal the end of the debug console's output (The command line terminal can detect this, so why can't ruby).
expect: In the program below the debugger inputs get out of sync with the debugger. Why is that?
require 'pty'
require 'expect'
$expect_verbose = true
PTY.spawn("rdebug deb.rb") do |from_debugger, to_debugger, pid|
a=nil
while ( a != "end" ) do
from_debugger.expect(/\(rdb:1\)/ ) do |input|
a = gets
to_debugger.puts( a + "\n" )
end
from_debugger.flush
end
end
I think you could make use of ruby-debug. I would imagine this as opening the same script on the server-side, and sending keystrokes to it. I think this is how I'd do it.
Think about it this way: the client pastes his code in your form. Optionally, he may click on some button that places a breakpoint on some line. Then he submits the whole thing. On server side, you process that form, and create a .rb file with the contents of the form. At the line where he put the breakpoint, you insert a debugger call. Then you run :
ruby client_script.rb
and this will stop the process once it reaches the debugger line. I would suggest you do all of this with Expect for Ruby or whatever. So, when the client presses step over on the page or inspect whatever variable, you send keystrokes to the process you spawned.
For example, if he wants to inspect the value of the variable x, you'd send this to the process:
p x
and you'd have to capture that output and send it back to the client's browser. Expect is kind of like popen , but a bit better.
I finally figured out how to do this using expect:
require 'pty'
require 'expect'
PTY.spawn("rdebug deb.rb") do |output,input,pid|
while true do
begin
buffer = ""
puts "-------"
puts output.readpartial(1024,buffer) until buffer =~ /\(rdb:1\)/
a = gets
input.puts a
rescue
break
end
end
end

Resources