See the current line being executed of a ruby script - ruby

I have a ruby script, apparently correct, that sometimes stops working (probably on some calls to Postgresql through the pg gem). The problem is that it freezes but doesn't produce any error, so I can't see the line number and I always have to isolate the line by using puts "ok1", puts "ok2", etc. and see where the script stops.
Is there any better way to see the current line being executed (without changing the script)? And maybe the current stack?

You could investigate ruby-debug a project that has been rewritten several times for several different versions of ruby, should allow you to step through your code line by line. I personally prefer printf debugging in a lot of cases though. Also, if I had to take an absolutely random guess at your problem, I might investigate whether or not you're running into a race condition and/or deadlock in your DB.

Related

Byebug terminal output is inconsistent and buggy

Whenever I drop a debugging breakpoint with byebug, I am noticing inconsistencies with the text that I type. For instance, I am able to type the first 2-3 characters. However, after the first 2-3 characters, the terminal starts adding random square brackets and other characters. For instance when I type env, Byebug outputs: eenv, or when I try to access a key in env Byebug outputs something even worse: ^[[Aenv['QUERY_STRING'']^[[.
Has anyone ran into this problem with Byebug?
A similar issue occurred to me while working in ruby on rails, using multiple workers. I am making the assumption here that OP is using rails because env and query strings are mentioned in the output.
So, if you are running multiple workers while debugging, they can cause this sort of behaviour, because code is still being executed after the byebug breakpoint is hit, and more importantly: while you try to type letters in the terminal, causing input to get jumbled. Debugging middleware can exacerbate this behaviour, since middleware is always hit, causing this issue to happen only while debugging certain components but not for an example controllers.
Ensure that only one worker is hitting your breakpoint at a time. This could be done by setting your development environment to never run more than 1 worker at least for the time being
This is a parallelization issue. Either with multiple workers while running rails server, OR in my case it was:
class ActiveSupport::TestCase
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors) # <--- this is a madness freaking root
end
byebug (and any bb-based gem) terminal input going nuts after hitting a break point in this case

How do I wrap a compiled command line tool for use in Ruby?

I have compiled and tested an open-source command line SIP client for my machine which we can assume has the same architecture as all other machines in our shop. By this I mean that I have successfully passed a compiled binary to others in the shop and they were able to use them.
The tool has a fairly esoteric invocation, a simple bash script piped to it prior to execution as follows:
(sleep 3; echo "# 1"; sleep 3; echo h) | pjsua sip:somephonenumber#ip --flag_1 val --flag_2 val
Note that the leading bash script is an essential part of the functioning of the program and that the line itself seems to be the best practice for use.
In the framing of my problem I am considering the following:
I don't think I can expect very many others in the shop to
compile the binary for themselves
Having a common system architecture in the shop it is reasonable to think that a repo can house the most up-to-date version
Having a way to invoke the tool using Ruby would be the most useful and the most accessible to the
most people.
The leading bash script being passed needs to be wholly extensible. These signify modifiable "scenarios" e.g. in this case:
Call
Wait three seconds
Press 1
Wait three seconds
Hang up
There may be as many as a dozen flags. Possibly a configuration file.
Is it a reasonable practice to create a gem that carries at its core a command line tool that has been previously compiled?
It seems reasonable to create a gem that uses a command line tool. The only thing I'd say is to check that the command is available using system('which psjua') and raising an informative error if it hasn't been installed.
So it seems like the vocabulary I was missing is extension. Here is a great stack discussion on wrapping up a Ruby C extension in a Ruby Gem.
Here is a link to the Gem Guides on creating Gems with Extensions.
Apparently not only is it done but there are sets of best practices around its use.

How can I detect how many levels down Pry has gone

If I'm at a Bash prompt and I type bash I can then detect that I'm at the 2nd level by typing echo $SHLVL.
Suppose I'm in a pry session and I type pry again. How can I detect that I'm at the 2nd level down? How can I detect the Pry level? Nothing listed in (Pry.methods - Object.methods).sort seems to have anything useful.
This is for testing some code for a pry-related project, where I need detect the level.
If you call caller within a pry session within a pry session, then you will see a list of commands. Among them, you should be able to find the part that corresponds to a nested pry call. Find the crucial line that is related to each pry session call, and you will know your level. As far as I checked, you should find two occurrences of a line like:
"/usr/local/lib/ruby/gems/2.2.0/gems/pry-0.10.1/lib/pry/repl.rb:67:in `repl'"
Count such lines.

Run the last X commands from IRB's command history?

I'm developing a ruby app with Vim in one screen, and in another I'm using irb to test the code I'm writing in Vim.
For the sake of this example, we'll say there are only 2 irb commands to test the code that I've written, a load and a method call.
Generally, it's more than 2 commands - if its just 2 I would tap the up arrow twice and hit enter, but generally its around 5 or 6 and that's up to 36 key presses just to run the last 6 commands. There must be an easier way.
Is there an easy way to execute the last X commands from the irb readline history buffer in the order they were executed, where X is the number of commands you want to run? Something like;
run_last_x_commands(i)
I'm pretty sure it would be a custom written piece of code, I'm just wondering if anyone already solved this problem or if this is something I'll need to write myself.
You may be interested in running Vim in IRB.
Gem.
Source.
I would really store your test script in a file. It is less convenient than just typing it out, but at the same time, it's easier to edit and work with. Plus, if you're trying to define classes, you often get issues with IRB not able to redefine a class without doing things like Object.remove_const('MyClass'). I've had the same problem you're having, and I decided against using IRB for this task.
There may be some readline magic to do what you want though. Readline has all kinds of tricks and shortcuts I don't know about.

Why is this Perl require line taking so much time?

I have a Perl script that runs via a system() command from C. On a specific site (SunOS 5.10), when that script is run, it nearly always takes 6 seconds or more. On other sites, it runs pretty much instantly (0.1s). If I run the script manually, i.e. not from the C code, it also runs instantly. I eventually tracked the slowness down (by spitting out the time a whole bunch in a lot of different places), to a single require line. The file that it is requiring is another Perl script we wrote. The script consists of a single require (this file here), 3 scalars that are assigned integer values, and a handful of time/date conversion routines. The file ends with a 1;. That single require appears to take as much as 6 seconds on occasion, but as I said, not always even on the same machine. I'm absolutely stumped here. My only last thought is to turn on profiling, but the site doesn't have Devel::Profiler and my only other option (that I know of) would be to add it to the Perl command which would require me altering and recompiling the C code (doable but non-trivial).
Anybody have ANY idea what could be going on here? I don't think I can/want to put the entire date.pl that is being required, but it's pretty much exactly as I described; I could answer any questions about it that you have.
Thanks in advance.
You might be interested in A Timely Start by Jean-Louis Leroy. He had a similar problem and tracked it down to a long and deep module search path where perl usually found the modules in the last entries in #INC.
Six seconds is a long time. Have you checked what your network is doing during this?
My first thought was that spawning the new process when using the system() command could be the problem, but six seconds is too long.
I don't know much about perl, but I could imagine that for any reason, the access of the time module could invoke a call to a network time server. Just to get synchronized. Maybe this takes so long or maybe it is getting a time out.
It could be that this only happens for a newly spawned process -- hence only when you use the system() command.
just wild guessing...
So, this does nothing to answer your question directly, but please tell me that you're not actually running on perl 4? Assuming you're on perl 5, you could remove the entire file and replace the require with use POSIX qw(ctime) to get the version that comes with Perl.
If you do have to support perl4, I'll merely grumble something about version 5 being fifteen years old now and go away. :)

Resources