How to overwrite standard puts method

I’m pretty new to ruby.
I’m using buildR to build our software.
When buildR runs in the trace mode it prints out a huge amount of
information to the standard output which is difficult to understand.

I would like to have a better control on the output format.
I thought about overwriting standard puts method and use log4R in the
new implementation to get better control on formatting/filtering.

Can it be done? Any other idea on how to get the better control on
buildR output?

Thanks in advance,
Arkady

On Thu, Oct 14, 2010 at 02:31:07AM +0900, Arkady Itkin wrote:

buildR output?
Have you tried using sprintf to format output before printing it?

You can probably redirect all that output to a file with >filename.txt
and then look at it at your convenience.

On 10/13/2010 07:31 PM, Arkady Itkin wrote:

buildR output?
There are several methods that write to stdout (off the top of my head
at least puts, print, printf). One option would be to assign to $stdout
another stream. If you want to catch child process output things get a
bit more complicated. In that case you either need to use IO#popen to
handle child process output or open a pipe and use $stdout.reopen to
attach the write end of the pipe to the stream. You then need to read
(asynchronously, i.e. in a thread) from the read end.

Btw, why is offline filtering not an option? I mean, if you write
stdout to a file you can filter whatever you like and you still have the
whole output.

Kind regards

robert

Robert K. wrote in post #949915:

On 10/13/2010 07:31 PM, Arkady Itkin wrote:

buildR output?
There are several methods that write to stdout (off the top of my head
at least puts, print, printf). One option would be to assign to $stdout
another stream. If you want to catch child process output things get a
bit more complicated. In that case you either need to use IO#popen to
handle child process output or open a pipe and use $stdout.reopen to
attach the write end of the pipe to the stream. You then need to read
(asynchronously, i.e. in a thread) from the read end.

Btw, why is offline filtering not an option? I mean, if you write
stdout to a file you can filter whatever you like and you still have the
whole output.

It looks like I did not explain my problem correctly.

I’m trying to debug a huge amount of buildR code which overflows me with
tons of information printed out.
Of course, I can redirect it to the file (both from within the code or
from command prompt) and then try to filter out the needed information
from the saved output. But since the output it’s not well
organized/structured it’s not an easy task.

I thought about replacing all puts/print etc. calls that exists in the
code by log4R which can be controlled from outside (and, on the way
provide better structured output).
Of course, I can find and replace puts/sprints etc. in the code to my
method. But this is huge amount of code and I’m lazy :-).

So, I thought about some trick which will allow me to overwrite standard
output methods like puts and get control of the output into my code
where I can do whatever I want. It may be useful for other people as
well when they need to debug the build code.

BTW, any other idea on how to debug buildR code will be appreciated. I
tried to use ruby debugger with it but it fails in attempt to load
buildR stuff.

Thanks in advance,
Arkady

On 14.10.2010 10:08, Arkady Itkin wrote:

from the saved output. But since the output it’s not well
organized/structured it’s not an easy task.

I thought about replacing all puts/print etc. calls that exists in the
code by log4R which can be controlled from outside (and, on the way
provide better structured output).

What kind of structure do you expect to get? As far as I can see
changing puts to internally delegate to a Logger can give you only
timestamp and maybe thread id because puts itself only accepts message
texts. You can especially not get log levels with this approach.

Of course, I can find and replace puts/sprints etc. in the code to my
method. But this is huge amount of code and I’m lazy :-).

So, I thought about some trick which will allow me to overwrite standard
output methods like puts and get control of the output into my code
where I can do whatever I want. It may be useful for other people as
well when they need to debug the build code.

Yes, of course you can do that. But I still wonder what kind of
structure beyond added timestamps you expect.

BTW, any other idea on how to debug buildR code will be appreciated. I
tried to use ruby debugger with it but it fails in attempt to load
buildR stuff.

Whenever I need to debug an ant build I use option -d (debug, really
verbose), let all output flow into a file and look at it with my
favorite text editor [1]. That supports setting bookmarks based on
search patterns (POSIX regexp), you can copy all bookmarked lines into a
new document etc.

Cheers

robert

[1] http://www.textpad.com/

Robert,

Thanks for the help.
Please, see my comments inside.

Arkady

Robert K. wrote in post #950193:

On 14.10.2010 10:08, Arkady Itkin wrote:

from the saved output. But since the output it’s not well
organized/structured it’s not an easy task.

I thought about replacing all puts/print etc. calls that exists in the
code by log4R which can be controlled from outside (and, on the way
provide better structured output).

What kind of structure do you expect to get? As far as I can see
changing puts to internally delegate to a Logger can give you only
timestamp and maybe thread id because puts itself only accepts message
texts. You can especially not get log levels with this approach.

I was thinking about getting information on caller of the “puts” method.
That will allow me to print out who invoked the “puts” method and even
print it with indentation reflecting calling stack.

Of course, I can find and replace puts/sprints etc. in the code to my
method. But this is huge amount of code and I’m lazy :-).

So, I thought about some trick which will allow me to overwrite standard
output methods like puts and get control of the output into my code
where I can do whatever I want. It may be useful for other people as
well when they need to debug the build code.

Yes, of course you can do that. But I still wonder what kind of
structure beyond added timestamps you expect.

BTW, any other idea on how to debug buildR code will be appreciated. I
tried to use ruby debugger with it but it fails in attempt to load
buildR stuff.

Whenever I need to debug an ant build I use option -d (debug, really
verbose), let all output flow into a file and look at it with my
favorite text editor [1]. That supports setting bookmarks based on
search patterns (POSIX regexp), you can copy all bookmarked lines into a
new document etc.

Unfortunately buildR trace is not as useful as ant trace. For example,
it does not print out the reason why it decides to trigger some task (at
least I did not find it).
Besides, contrary to ant, buildR is not pure declaration language but
allows to write custom code which I want to debug. I wonder if I can use
ruby debugger ti debug this code (meanwhile all my attempts failed, ruby
debugger fails to load with builrR).

Thanks,

Arkady

Cheers

robert

[1] http://www.textpad.com/

On 17.10.2010 08:57, Arkady Itkin wrote:

What kind of structure do you expect to get? As far as I can see
changing puts to internally delegate to a Logger can give you only
timestamp and maybe thread id because puts itself only accepts message
texts. You can especially not get log levels with this approach.

I was thinking about getting information on caller of the “puts” method.
That will allow me to print out who invoked the “puts” method and even
print it with indentation reflecting calling stack.

You should then probably look into set_trace_func as another option.
With that you can do custom logging of all methods invoked.

-------------------------------------------------- Kernel#set_trace_func
set_trace_func(proc) => proc
set_trace_func(nil) => nil

  From Ruby 1.9.1

  Establishes _proc_ as the handler for tracing, or disables tracing
  if the parameter is +nil+. _proc_ takes up to six parameters: an
  event name, a filename, a line number, an object id, a binding, 

and
the name of a class. proc is invoked whenever an event occurs.
Events are: +c-call+ (call a C-language routine), +c-return+
(return from a C-language routine), +call+ (call a Ruby method),
+class+ (start a class or module definition), +end+ (finish a
class
or module definition), +line+ (execute code on a new line),
+raise+
(raise an exception), and +return+ (return from a Ruby method).
Tracing is disabled within the context of proc.

      class Test
      def test
        a = 1
        b = 2
      end
      end

      set_trace_func proc { |event, file, line, id, binding, 

classname|
printf “%8s %s:%-2d %10s %8s\n”, event, file, line, id,
classname
}
t = Test.new
t.test

        line prog.rb:11               false
      c-call prog.rb:11        new    Class
      c-call prog.rb:11 initialize   Object
    c-return prog.rb:11 initialize   Object
    c-return prog.rb:11        new    Class
        line prog.rb:12               false
        call prog.rb:2        test     Test
        line prog.rb:3        test     Test
        line prog.rb:4        test     Test
      return prog.rb:4        test     Test

You can try it out with a simple example like this:

ruby19 -e ‘set_trace_func lambda {|*a| p a};5.times {|i| p i}’

Unfortunately buildR trace is not as useful as ant trace. For example,
it does not print out the reason why it decides to trigger some task (at
least I did not find it).
Besides, contrary to ant, buildR is not pure declaration language but
allows to write custom code which I want to debug. I wonder if I can use
ruby debugger ti debug this code (meanwhile all my attempts failed, ruby
debugger fails to load with builrR).

Kind regards

robert

Robert,

Thanks a lot!
set_trace_func is exactly what I was looking for.

Arkady