www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Does D have a tool like pySnooper?

reply Taylor Hillegeist <taylorh140 gmail.com> writes:
Saw this tool and thought D could probably do something like this 
pretty easily. Is there such a tool out there already?

https://github.com/cool-RR/pysnooper

Or would this not be easy at all with D?
Apr 22 2019
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist wrote:
 Or would this not be easy at all with D?
I don't think so. While there are lots of traits for introspection of declarations, there is no way to introspect lines of code. The whole function would need to be wrapped into a mixin, and the D code would need to be parsed at compile time for this to work. It could be possible for the compiler to do this, similar to how it inserts counter increments every line when compiling with -cov for code coverage, but currently it doesn't.
Apr 25 2019
parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Thursday, 25 April 2019 at 08:44:14 UTC, Dennis wrote:
 On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist 
 wrote:
 Or would this not be easy at all with D?
I don't think so. While there are lots of traits for introspection of declarations, there is no way to introspect lines of code. The whole function would need to be wrapped into a mixin, and the D code would need to be parsed at compile time for this to work.
Yes, but I think that might be doable. You wouldn't need a full blown D parser, just one that can identify statements (`;` being an important clue). Not sure whether __LINE__ will be meaningful inside a mixin, though, but that might also be fixable. It would be an interesting challenge. Bastiaan.
Apr 26 2019
parent reply Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Friday, 26 April 2019 at 08:35:57 UTC, Bastiaan Veelo wrote:
 On Thursday, 25 April 2019 at 08:44:14 UTC, Dennis wrote:
 On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist 
 wrote:
 Or would this not be easy at all with D?
I don't think so. While there are lots of traits for introspection of declarations, there is no way to introspect lines of code. The whole function would need to be wrapped into a mixin, and the D code would need to be parsed at compile time for this to work.
Yes, but I think that might be doable. You wouldn't need a full blown D parser, just one that can identify statements (`;` being an important clue). Not sure whether __LINE__ will be meaningful inside a mixin, though, but that might also be fixable. It would be an interesting challenge. Bastiaan.
Proofing the concept: --- mixin(snoop(q{ int fun(int a, int b) { int c = 3; foreach (i; 1 .. 5) { a += i; } int d = a + b + c; return d; } })); --- Output: 2019-Apr-26 10:33:46.0935135 executed line 7: int c = 3; 2019-Apr-26 10:33:46.0936716 executed line 10: a += i; 2019-Apr-26 10:33:46.0937348 executed line 10: a += i; 2019-Apr-26 10:33:46.0937963 executed line 10: a += i; 2019-Apr-26 10:33:46.0938583 executed line 10: a += i; 2019-Apr-26 10:33:46.0939622 executed line 12: int d = a + b + c; https://run.dlang.io/is/Go97hQ Bastiaan.
Apr 26 2019
parent reply Taylor Hillegeist <taylorh140 gmail.com> writes:
On Friday, 26 April 2019 at 10:22:49 UTC, Bastiaan Veelo wrote:
 On Friday, 26 April 2019 at 08:35:57 UTC, Bastiaan Veelo wrote:
 On Thursday, 25 April 2019 at 08:44:14 UTC, Dennis wrote:
 On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist 
 wrote:
 Or would this not be easy at all with D?
I don't think so. While there are lots of traits for introspection of declarations, there is no way to introspect lines of code. The whole function would need to be wrapped into a mixin, and the D code would need to be parsed at compile time for this to work.
Yes, but I think that might be doable. You wouldn't need a full blown D parser, just one that can identify statements (`;` being an important clue). Not sure whether __LINE__ will be meaningful inside a mixin, though, but that might also be fixable. It would be an interesting challenge. Bastiaan.
Proofing the concept: --- mixin(snoop(q{ int fun(int a, int b) { int c = 3; foreach (i; 1 .. 5) { a += i; } int d = a + b + c; return d; } })); --- Output: 2019-Apr-26 10:33:46.0935135 executed line 7: int c = 3; 2019-Apr-26 10:33:46.0936716 executed line 10: a += i; 2019-Apr-26 10:33:46.0937348 executed line 10: a += i; 2019-Apr-26 10:33:46.0937963 executed line 10: a += i; 2019-Apr-26 10:33:46.0938583 executed line 10: a += i; 2019-Apr-26 10:33:46.0939622 executed line 12: int d = a + b + c; https://run.dlang.io/is/Go97hQ Bastiaan.
Hey, that's a pretty cool demo. I saw the idea and wondered rather it could be possible with D. I has some very cool introspection properties. The Link seems to be broken right now. But I think this might be worth some development. Tools like this can really help new users, especially when they are doing things the o'l fashion way, printf for debugging. I doubt it would be too much help for things like ranges, but one must pick their battles. Thanks.
Apr 26 2019
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Apr 26, 2019 at 02:33:16PM +0000, Taylor Hillegeist via
Digitalmars-d-learn wrote:
 On Friday, 26 April 2019 at 10:22:49 UTC, Bastiaan Veelo wrote:
[...]
 Proofing the concept:
 ---
 mixin(snoop(q{
     int fun(int a, int b)
     {
         int c = 3;
         foreach (i; 1 .. 5)
         {
             a += i;
         }
         int d = a + b + c;
         return d;
     }
 }));
 ---
 
 Output:
 2019-Apr-26 10:33:46.0935135 executed line 7:	        int c = 3;
 2019-Apr-26 10:33:46.0936716 executed line 10:	            a += i;
 2019-Apr-26 10:33:46.0937348 executed line 10:	            a += i;
 2019-Apr-26 10:33:46.0937963 executed line 10:	            a += i;
 2019-Apr-26 10:33:46.0938583 executed line 10:	            a += i;
 2019-Apr-26 10:33:46.0939622 executed line 12:	        int d = a + b +
 c;
Now *this* is some seriously cool stuff. [...]
 [...] Tools like this can really help new users, especially when they
 are doing things the o'l fashion way, printf for debugging.
I debug using printf/writeln too. As Nick would say, it gives you a fully-rewindable log of what actually happened in the code, and is often useful where a full debugger wouldn't be able to run (e.g., on embedded platforms with tight memory/CPU constraints). That, and also that D debugger support is currently rather anemic; in gdb, for example, many symbols are not recognized and/or their values are inaccessible. Stacktraces are supposed to give line numbers, but I haven't seen those in a while, even with -g. (At least it now gives at least the (mangled) function names; it used to be just a bunch of hex addresses that you have to decipher yourself.) I would contribute to debugger support, but unfortunately I don't actually use debuggers often enough to warrant the effort.
 I doubt it would be too much help for things like ranges, but one must
 pick their battles.
[...] If you're talking about UFCS chains, there's std.range.tee that lets you see what's going on in the middle of the chain without changing the type required for the next step in the pipeline. It's not as convenient, but a LOT better than having to split up a long UFCS chain just to insert debug code. T -- Life is complex. It consists of real and imaginary parts. -- YHL
Apr 26 2019
parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Friday, 26 April 2019 at 16:59:15 UTC, H. S. Teoh wrote:
 On Fri, Apr 26, 2019 at 02:33:16PM +0000, Taylor Hillegeist via 
 Digitalmars-d-learn wrote:
 On Friday, 26 April 2019 at 10:22:49 UTC, Bastiaan Veelo wrote:
[...]
 Proofing the concept:
 ---
 mixin(snoop(q{
     int fun(int a, int b)
     {
         int c = 3;
         foreach (i; 1 .. 5)
         {
             a += i;
         }
         int d = a + b + c;
         return d;
     }
 }));
 ---
 
 Output:
 2019-Apr-26 10:33:46.0935135 executed line 7:	        int c 
 = 3;
 2019-Apr-26 10:33:46.0936716 executed line 10:	            a 
 += i;
 2019-Apr-26 10:33:46.0937348 executed line 10:	            a 
 += i;
 2019-Apr-26 10:33:46.0937963 executed line 10:	            a 
 += i;
 2019-Apr-26 10:33:46.0938583 executed line 10:	            a 
 += i;
 2019-Apr-26 10:33:46.0939622 executed line 12:	        int d 
 = a + b +
 c;
Now *this* is some seriously cool stuff.
Thanks! A limitation is that snoop() needs to be pure. At one time I had a byLine in there, but for some reason byLine is not pure so that didn't work. I was almost about to see if I could use libdparse in it (run.dlang.io supports it) but I should spend my time on preparing for DConf instead... Feel free to play with it, this stuff is fun! Bastiaan.
Apr 26 2019
prev sibling parent Cym13 <cpicard openmailbox.org> writes:
On Monday, 22 April 2019 at 16:24:53 UTC, Taylor Hillegeist wrote:
 Saw this tool and thought D could probably do something like 
 this pretty easily. Is there such a tool out there already?

 https://github.com/cool-RR/pysnooper

 Or would this not be easy at all with D?
First line of that link: "PySnooper is a poor-man's debugger". I don't think it is possible to do what PySnooper does at runtime without significantly changing the code you write to accomodate it, D and Python are just structured too differently. However I see no advantage in having something like PySnooper either because D has real debuggers. Using gdb you can do everything that pysnooper does, dynamically and with the corresponding lines of code. You also get much much more such as memory inspection, memory modification, disassembly or the magical ability to rewind time from a crash. PySnooper is nice for python, but I fail to see any advantage over a real debugger in D.
Apr 27 2019