How to print the current lines in Ruby one by one? - ruby

I would like to print out the actual line in Ruby for demonstrative purposes to demonstrate the working of a Ruby CGI application: it would send the actual line by an AJAX call response to a webpage, and then simply wait a few seconds or for some user action.
I know there is a __LINE__ variable, which contains the actual line number. I would like to install a signal trap, "variable watch" or other similar interrupt mechanism which is always called when __LINE__ is changing, or if there is any dedicated interrupt which is always called and can be registered for this purpose. How can I achieve this?

Have you tried http://ruby-doc.org/core-2.2.3/Kernel.html#method-i-caller ?
With this, you scan call trace and find first related file, then extract line number with something like /\d+(?=:in)/

Related

See the current line being executed of a ruby script

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.

Lua hook-like call AFTER line processing

Lua features hook call BEFORE every processed line. What I need is a call AFTER line is processed, so that I can check for encountered errors and so on. Is there a way to make such kind of call?
Otherwise things get a little bit confusing if error is encountered at the last line of the script. I don't get any feedback.
UPDATE #1
We want to catch both Lua errors and 'our' errors asserted via lua_error(*L) C interface, and Lua should throw correct debug info including the line number where the error occurred.
Using return hook we always get error line number -1, which is not what we want. Using any combination of pcall and any hook setup after lua_error(*L) we get either line number -1, or number of the next executed line, never a correct one.
SOLUTION#
We managed to make everything work. The thing was that Lua throws a real C exception after it detects an error, so some of our 'cleaning & finalizing' C code called from Lua operation did not execute, which messed up some flags and so on. The solution was to execute 'cleaning code' right before calling lua_error(...). This is correct and desired Lua behavior as we really want to stop executing the function once lua_error(...) is called, it was our mistake to expect any code would be executed after lua_error(...) call.
Tnx Paul Kulchenko, some of this behavior was found while trying to design a simple example script which reproduces the problem.
Try setting a return hook: it'll be called after the last line is executed.
I'm not sure debug hook is the best solution for what you are trying to do (or you need to provide more details). If you just need to check for run-time errors, why use debug hooks at all if you can run your code with pcall and get an error message that points to the line number where the error happened (or use xpcall, which also allows you to get a stack trace)? You can combine this with debug.getinfo(func, "L") to get a table whose indexes are valid line numbers for the function.

How do I write to the console regardless of whether or not the user uses `|` or `>` operators on the shell?

I wrote a program in Ruby and have been writing all data to the console with puts.
If I run my.rb from the console I can redirect the stream to a file both with > and |.
How should I change stdout in order for data to be written to the Windows console?
The whole idea of those symbols is to allow users of your app to redirect the output to their desired place. This is useful for logging, filtering, and any number of other applications where you want the output of one program to be the input of another program or file. It's facilitates a form of inter-process communication that often isn't possible otherwise.
Essentially, unless you can more clearly define the reason you want to do this (a specific case where this is useful and desirable) you should not try to do this, nor am I sure it's even possible, because those symbols operate at the shell level. I don't think there is anything within the scope of Ruby that you can do what will have any effect whatsoever on where the output goes. The shell (after it's already left your Ruby program) is capturing that output and redirecting it. By that point, that data/output is already out of the control of your Ruby app.
If you are trying to differentiate from real "output" and error messages that the user should see, you can instead send output to the standard error output with something like:
$stderr << 'oh noes!'
The standard error output is redirected independently from the standard output.

Help in understanding this bash file

I am trying to understand the code in this page: https://github.com/corroded/git-achievements/blob/gh-pages/git-achievements
and I'm kinda at a loss on how it actually works. I do know some bash and shell scripting, but how does this script actually "store" how many times you've used a command(im guessing saving into a text file?) and how does it "sense" that you actually typed in a git command? I have a feeling it's line 464 onwards that does it but I don't seem to quite follow the logic.
Can anyone explain this in a bit more understandable context?
I plan to do some achievements for other commands and I hope to have an idea on HOW to go about it without randomly copying and pasting stuff and voodoo.
Yes on 464 start the script, everything before are helping functions. I dont know how it gets installed, but I would assume you have to call this script instead of the normal git-command. It just checks if the first parameter is achievement, and if not then just (regular) git with the rest parameters is executed. Afterwards he checks if an error happend (if he exits). And then he just makes log_action and check_for_achievments. log_action just writes the issued command with a date into a text file, while achievments scans for that log file for certains events. If you want to add another achievment you have to do it in this check_for_achievments.
Just look how the big case handles it (most of the achievments call the count_function which counts the # usages of the function and matches when a power of 2 is reached).

How do I detect when output is being redirected?

I have a Win32 application written in C that can have its console output via printf() redirected to a log file.
It would be nice if I could have my app. detect if it had been started with or without a redirect '>'.
Any ideas?
Tom, thanks for the input.
I did some experiments and found this works for me..
fpost_t pos ;
fgetpos (stdout, & pos) ;
When an application's output is being redirected to a file, fgetpos() sets 'pos' to zero. It makes sense since its freshly opened stderr for you. EDIT: Actually, the value returned may be a positive integer if text has already been redirected to the log/file. So in your code you'd have something like "if (pos >= 0) bfRedirected = TRUE ;"
When an application's output is not being redirected - it's going to the console device - not a file, so fgetpos() will set 'pos' to -1.
I think that pipes are blind by nature, so you don't have a built-in way to tell whether you're being redirected. Moreover, trying to find out what's happening behind an abstraction layer is a bad habit.
If you really need to control your output, add the log file name as a command line parameter!
That being said, you can make some smart guesswork to find out:
A program can query the shell command history to find out the most recent commands executed.
If you know the path to the logfiles, you can scan that directory and see if a file has been created or changed its size.
Benchmark writing speed when redirected and not redirected. This would work only if your system is ultra-stable, and environment condition won't change.
There may be a way to do this - a quick google yielded this hit that might give you the hint in the right direction.
Method from Microsoft: WriteConsole fails if it is used with a standard handle that is redirected to a file. If an application processes multilingual output that can be redirected, determine whether the output handle is a console handle (one method is to call the GetConsoleMode function and check whether it succeeds).
AFAIK the answer to this is that you can't. Output redirection works by simply reading the stream of output from a given program and redirecting it to another pipe / stream. The design of file / streams is such that the writer is ignorant of the reader to the point that you shouldn't know you are being read.
Even detecting that there was a reader would be of no use because there is one in the normal case. The console is reading the output of your program and displaying it to the screen already.

Resources