How to overwrite standard puts method

A

Arkady Itkin

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
 
R

Robert Klemme

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?

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
 
D

DaShiell, Jude T. CIV NAVAIR 1490, 1, 26

WW91IGNhbiBwcm9iYWJseSByZWRpcmVjdCBhbGwgdGhhdCBvdXRwdXQgdG8gYSBmaWxlIHdpdGgg
PmZpbGVuYW1lLnR4dCBhbmQgdGhlbiBsb29rIGF0IGl0IGF0IHlvdXIgY29udmVuaWVuY2UuDQoN
Ci0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQpGcm9tOiBBcmthZHkgSXRraW4gW21haWx0bzph
aXRraW5Ab3B0aWVyLmNvbV0gDQpTZW50OiBXZWRuZXNkYXksIE9jdG9iZXIgMTMsIDIwMTAgMTM6
MzENClRvOiBydWJ5LXRhbGsgTUwNClN1YmplY3Q6IEhvdyB0byBvdmVyd3JpdGUgc3RhbmRhcmQg
cHV0cyBtZXRob2QNCg0KSSdtIHByZXR0eSBuZXcgdG8gcnVieS4NCkknbSB1c2luZyBidWlsZFIg
dG8gYnVpbGQgb3VyIHNvZnR3YXJlLg0KV2hlbiBidWlsZFIgcnVucyBpbiB0aGUgdHJhY2UgbW9k
ZSBpdCBwcmludHMgb3V0IGEgaHVnZSBhbW91bnQgb2YNCmluZm9ybWF0aW9uIHRvIHRoZSBzdGFu
ZGFyZCBvdXRwdXQgd2hpY2ggaXMgZGlmZmljdWx0IHRvIHVuZGVyc3RhbmQuDQoNCkkgd291bGQg
bGlrZSB0byBoYXZlIGEgYmV0dGVyIGNvbnRyb2wgb24gdGhlIG91dHB1dCBmb3JtYXQuDQpJIHRo
b3VnaHQgYWJvdXQgb3ZlcndyaXRpbmcgc3RhbmRhcmQgcHV0cyBtZXRob2QgYW5kIHVzZSBsb2c0
UiBpbiB0aGUNCm5ldyBpbXBsZW1lbnRhdGlvbiB0byBnZXQgYmV0dGVyIGNvbnRyb2wgb24gZm9y
bWF0dGluZy9maWx0ZXJpbmcuDQoNCkNhbiBpdCBiZSBkb25lPyBBbnkgb3RoZXIgaWRlYSBvbiBo
b3cgdG8gZ2V0IHRoZSBiZXR0ZXIgY29udHJvbCBvbg0KYnVpbGRSIG91dHB1dD8NCg0KVGhhbmtz
IGluIGFkdmFuY2UsDQpBcmthZHkNCg0KLS0gDQpQb3N0ZWQgdmlhIGh0dHA6Ly93d3cucnVieS1m
b3J1bS5jb20vLg0KDQo=
 
A

Arkady Itkin

Robert Klemme wrote in post #949915:
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
 
R

Robert Klemme

Robert Klemme wrote in post #949915:
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).

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/
 
A

Arkady Itkin

Robert,

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

Arkady


Robert Klemme wrote in post #950193:
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
 
R

Robert Klemme

Robert Klemme wrote in post #950193:

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
 
A

Arkady Itkin

Robert,

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

Arkady
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top