app is not stopping at "gets" - is my online interpreter forcing a timeout? - ruby

While starting an assignment (Towers of Hanoi), I leave my code in a very basic state while I ponder the logic of how to continue.
while arr3.count < 6
puts "Move ring FROM which tower?"
from = gets.chomp
puts "Move ring TO which tower?"
to = gets.chomp
end
Before I can start building the rest of the app, however, gets seems to fall through without any input from me, and the second puts displays on the screen. This continues looping every, say, 30 seconds or so. Should I assume this is a feature of online interpreters (like codeacademy labs)?
Now I'm distracted from continuing the assignment and have to find a better place to do my code.
I'm installing Aptana (based on some advice on this forum) to see if I can get a better environment to do my assignments. Or do most people use a text editor then run their .rb file through the windows console window?
Thx

Related

What could be causing ruby NoMethodError backtrace to be so slow?

I have a pretty large ruby (non-rails) application that I'm developing. It's reasonably fast considering how large and complex it is (go ruby!), but sometimes I fat finger a method name and get the NoMethodError.
And usually when this happens, the application hangs for like 20 to 30 seconds to just print out the backtrace.
Specifically, if I do something like this:
puts "about to crash!"
Array.new().inspekt # NoMethodError here
I see the "about to crash!" right away, and then 20s or so nothing seems to happen before I finally get the NoMethodError and backtrace.
At first I thought it might be the "did you mean" gem, so I turned that off with --disable-did_you_mean on the command line, and that turned off the "did you mean" suggestions, but nothing sped up the backtrace.
What's interesting is that this is only for NoMethodError.
If I cause some other exception, such as:
puts "about to crash!"
a = 3/0
Then I see the backtrace immediately.
And to make things even weirder, if I interrupt the process right after the "about to crash!" (such as with a ctrl-c on unix) then I immediately get the NoMethodError and it's backtrace. So it has the information - but ruby is stuck on trying to clean something up perhaps, something that only gets cleaned up on NoMethodError?
Info: ruby 2.7.0
OS: CentOS Linux release 7.5.1804
UPDATE - to responses so far:
Everyone seems to be concerned about the backtrace and profiling the ruby code.
Except the slowdown is NOT happening there. There are NO LINES OF RUBY CODE that are executed during the slowdown. All of the lines prior to this, "in the backtrace" are already executed and in a matter of a second or so. Then the system hangs, between the puts and the NoMethodError. There is no ruby code in between to profile, so any profiler that is looking at code written in my ruby script isn't going to help. The slowdown is something internal to ruby and is not in my code, unless I'm terribly confused about what's happening.
To be very clear:
Line 10042: puts "HERE" # Happens at ~1s
Line 10043: Array.new().inspekt # Happens at ~20-30s
There is no code between those lines to profile. The 20-30s is not happening in any code before line 10042 executes, so profiling that will not help.
I do have other Fibers that are paused. But there is no code here that yields to them. Is it possible that there's some strange built-in yield code that attempts to run other (paused) fibers when an exception is hit? I can't think of a reason you'd ever want this behavior, and many reasons why it would be catastrophic, but I can't think of anything else that would cause this problem (that is also killable with a ctrl-c!)
I would try to debug the full backtrace in there to see what is actually happening
begin
puts "about to crash!"
Array.new().inspekt
rescue => e
puts e.backtrace
raise # raise anyway
end
In my case I get 20 lines of backtrace with ruby 2.6.3 and irb, if that doesn't really tell you anything interesting I would then do the tedious work of measuring each runtime by modifying each file of the backtrace and printing the times at each step, debugging yay!

AppleScript: Edit a fully written script buy "whiting out" certain commands but leaving it in so you can remember it

I've compiled my first web crawler script with AppleScript and I'm at the point now where I've gained a lot of knowledge and tricks from what I've written. I want to parse down the script now and disable some things that I thought would be helpful (for example: I coded it so the script completely quits Excel after entering the data in some workbooks from web pages because I noticed when you didn't start Excel fresh running the code it would return an error. But now I have the script running every 15 minutes so I worry that I will be working in Excel on some forecasting or formatting and the script will run and kick me out of Excel while I'm working and interrupt me or worse, quit without the option of saving). I vaguely remember C++ coding there was the ability to mark some text with a certain character that disabled it from running in the environment but made it so you could still see the original code before editing out stuff you decided wasn't necessary. Is there a way to mark a certain statement with a symbol so that AppleScript doesn't run the commands? I haven't experimented at all but I don't know what to guess that would do it. I may be mistaken that you can blank out or "white out" text while leaving it in the original position, still readable and able to be put back in when you want it or left for you so you have a collection of all the research you put into the process of building a script for a project. Well I suppose I'll just wonder a while and find something else to burn hours on.
In applescript there are three ways to "comment" out text in your code.
--A line beginning with two dashes is a comment.
#In applescript 2.+, the number sign also works as a comment symbol.
(* Multi-line text
can be commented out
using these symbols. *)

remove and replace the text when putting a string into the console $stdin ruby

I have a program that is a client, talking to a server with socket.
When the user is inputting a message, if another message comes in, it breaks up the text visually, making it hard to understand for the user.
the scenario can be thought up like this
c=0
p=Thread.new do
loop {
# this is the messages coming in
c+=1
puts c
sleep 1
}
end
g=Thread.new do
loop {
#this is the user input
puts $stdin.gets
}
end
p.join
g.join
in the case of some really slow typers, the output looked similar to this
1
h2
el3
l4
o5
hello
6
Is there any way to remove and replace the text when putting a string into the console?
edit
So, now if i can get each character separate, i can add it to a string, and in the thread p when it puts, it will put "\r" + c and then print the string.
this would allow the user to still see what they are typing, as well as not interrupting the p thread.
I dont know how to get each character individually.
this also brings up the problem of "how would backspace work?" and "would i need a switch statement for special characters like return and ctrl+c?"
If you are trying to implement a chat app in terminal, the "appropriate" tool is curses. A curses library essentially lets you write a GUI in the terminal. It lets you define separate regions of the screen that you can update separately and also lets you read input without echoing it to the terminal.
Your program is multithreaded, and both of your threads are fighting over the same resource: the terminal! The classic way to handle this is to protect the shared resource with a mutex.
The idea is simple: whenever a thread interacts with the shared resource (the terminal) synchronize that access with the shared mutex. That way they don't stomp on each other.
But your situation is tricky, it's easy to see when thread p wants to use the terminal, but it's not easy in thread g because that's just the user typing. What you probably would have to do is use IO#read_nonblock in a tight loop to get the user's input character-by-character. You could then use that to detect when the user pauses their input and take that moment to unlock the mutex, allowing the other thread to dump its output.
Note that this will also make thread p more complicated because it needs to be able to buffer its output while it's waiting for the terminal to become available.

How do I create this File Input and Output assignment in Ruby

I have an assignment that I am not sure what to do. Was wondering if anyone could help. This is it:
Create a program that allows the user to input how many hours they exercised for today. Then the program should output the total of how many hours they have exercised for all time. To allow the program to persist beyond the first run the total exercise time will need to be written and retrieved from a file.
My code is this so far:
myFileObject2 = File.open("exercise.txt")
myFileObjecit2.read
puts "This is an exercise log. It keeps track of the number hours of exercise."
hours = gets.to_f
myFileObject2.close
Write your code like:
File.open("exercise.txt", "r") do |fi|
file_content = fi.read
puts "This is an exercise log. It keeps track of the number hours of exercise."
hours = gets.chomp.to_f
end
Ruby's File.open takes a block. When that block exits File will automatically close the file. Don't use the non-block form unless you are absolutely positive you know why you should do it another way.
chomp the value you get from gets. This is because gets won't return until it sees a trailing END-OF-LINE, which is usually a "\n" on Mac OS and *nix, or "\r\n" on Windows. Failing to remove that with chomp is the cause of much weeping and gnashing of teeth in unaware developers.
The rest of the program is left for you to figure out.
The code will fail if "exercise.txt" doesn't already exist. You need to figure out how to deal with that.
Using read is bad form unless you are absolutely positive the file will always fit in memory because the entire file will be read at once. Once it is in memory, it will be one big string of data so you'll have to figure out how to break it into an array so you can iterate it. There are better ways to handle reading than read so I'd study the IO class, plus read what you can find on Stack Overflow. Hint: Don't slurp your files.

how to produce delay in ruby

How to produce delay in ruby?
I used sleep statement but it didn't give me what I want.
puts "amit"
sleep(10)
puts "scj"
I want it to first print amit, then a delay of 10 seconds, then print scj.
But in above case what happens is it will pause for 10 seconds and then it will print amit and scj together. I don't want that.
I hope you got what I want to say.
I can't reproduce this. From a console, this does exactly what you'd expect:
puts "amit"
sleep 10
puts "scj"
(Ruby 1.8.6 on Linux)
Can you provide a similar short but complete example which doesn't do what you want - or explain your context more?
If you're writing a web application, then the browser may well only see any data once the whole response has been written - that would explain what you're seeing. If that's the case, you'll need a different approach which would allow the initial response to be written first, and then make the browser make another request. The delay could be at the server or the client, depending no the scenario.
Call $stdout.flush before the call to sleep. The output is probably buffered (although usually output is only line-buffered so puts, which produces a newline, should work without flushing, but apparently that's not true for your terminal).

Resources