From: "Florian Groß" Date: 2006-03-05T04:20:09+09:00 Subject: Re: Review requested: Binding.call_stack(), Binding.of_caller()-style --------------050605030406090106090309 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Dumaiu wrote: > I'd like to submit for evaluation an elaboration I've made on the > famous 'Binding.of_caller()' of Florian Gro�. I have tried to follow > the the description of the interface for Binding.call_stack() suggested > in ruby-talk 12097, "RCR: replacing 'caller'", although in standard > Ruby instead of an extension. > The technique of using set_trace_func() to capture a Binding one > stack frame up has been around at least since 2001 [1]. Here I raise > an exception and ride it out to main scope, catching Bindings as the > stack unrolls. File and line info is taken from caller() as usual, and > the input from the two traces is knitted together. Wow, that's some pretty innovative, clever and great thinking going on there. I haven't even thought about doing this, yet. Nice idea. However, I see a problem with it: If you throw() through methods that have an ensure block the ensure block will get executed. This is demonstrated in the attached example. (I also attached your code because it was damaged in your mail by being wrapped.) I thought we might be able to fly through ensure blocks without executing them by raising the fatal exception, but it appears that Ruby will even run them in that case... If you can find a way of making it work correctly with the attached test then you have an implementation that is a lot more powerful than mine which means I can finally drop my implementation... :) > I would appreciate your input with regard to the following: > * The three class attributes mentioned above (and the version member) > allow noninvasive tweaking, but I'm not sure whether I should be using > class variables or class instance vars for them. I'd just hard code the actual classes instead. I see no purpose in being able to change the type of data it returns anyway. If you need to convert it to another format, you can always just do that. > * I noticed that Herr Gro� renders his script thread critical(). I > know not enough about thread safety to incorporate this without dumbly > parroting him. The trace func isn't thread local, but you want it to be. The only way of working around that is by temporarily stopping all other threads. > * Use of set_trace_func() breaks compatibility with the debugger, and > I haven't had much luck with irb, either. Under what other > circumstances do Binding.of_caller() and relatives not work well? When there already is a trace_func. :) It's also a problem when using -rtrace. Binding.of_caller ought to work in IRB, but I'm not 100% sure. > Finally: I've only been in Ruby for a little over a month, so if it > looks somewhere like I don't know what I'm doing, that's probably the > case. :-) And you are sure you really want to get involved into this kind of black magic already? :) Well, it already seems to be paying off so who am I to ask? :) -- http://flgr.0x42.net/ --------------050605030406090106090309 Content-Type: application/x-ruby; name="call_stack.rb" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="call_stack.rb" IyBCSU5ESU5HDQpjbGFzcyBCaW5kaW5nDQogIHJlcXVpcmUgJ3Rlc3QvdW5pdC9hc3NlcnRp b25zJw0KICBjbGFzcyA8PCBzZWxmDQogICAgaW5jbHVkZSBUZXN0OjpVbml0OjpBc3NlcnRp b25zICMgZm9yIEJpbmRpbmc6OmNhbGxfc3RhY2sNCiAgZW5kDQoNCiAgIyAqKioqKioqKioq KioqKiogU1RBQ0tGUkFNRSAqKioqKioqKioqKioqKioNCiAgY2xhc3MgU3RhY2tGcmFtZQ0K ICAgIGluY2x1ZGUgVGVzdDo6VW5pdDo6QXNzZXJ0aW9ucw0KDQogICAgIyBUT0RPOiBNYWtl IHJlYWQtb25seToNCiAgICBhdHRyX2FjY2Vzc29yIDpvYmplY3QNCiAgICBhdHRyX2FjY2Vz c29yIDptZXRob2QNCiAgICBhdHRyX2FjY2Vzc29yIDpiaW5kaW5nDQogICAgYXR0cl9hY2Nl c3NvciA6ZmlsZQ0KICAgIGF0dHJfYWNjZXNzb3IgOmxpbmUNCg0KICAgICMgdG9fYSgpOiBS ZXR1cm4gZGF0YSBhcyBuZXcgYXJyYXkuDQogICAgZGVmIHRvX2EoKQ0KICAgICAgcmV0dXJu IFsgc2VsZi5vYmplY3QsDQogICAgICAgIHNlbGYubWV0aG9kLA0KICAgICAgICBzZWxmLmJp bmRpbmcsDQogICAgICAgIHNlbGYuZmlsZSwNCiAgICAgICAgc2VsZi5saW5lDQogICAgICBd DQogICAgZW5kIyB0b19hKCkNCg0KICAgICMgdG9fcygpOiBSZXR1cm4gam9pbigpZWQgc3Ry aW5nLg0KICAgIGRlZiB0b19zKCkNCiAgICAgIHJldHVybiB0b19hKCkudG9fcygpDQogICAg ZW5kIyB0b19zKCkNCg0KICAgICMgaW5zcGVjdCgpOiBSZXR1cm4gYXMgYXJyYXkgb2YgdmFs dWVzLg0KICAgIGRlZiBpbnNwZWN0KCkNCiAgICAgIHJldHVybiB0b19hKCkuaW5zcGVjdCgp DQogICAgZW5kIyBpbnNwZWN0KCkNCg0KICAgICMgdG9faCgpOiBSZXR1cm4gaW4ga2V5L3Zh bHVlIGZvcm0uICBOb3RlOiBBIHBhaXIgd2lsbCBvbmx5IGV4aXN0IGlmIGFjY2Vzc29yIGFz c2lnbm1lbnQgaGFzIGJlZW4gdXNlZC4NCiAgICBkZWYgdG9faCgpDQogICAgICBoID0gSGFz aDo6bmV3DQogICAgICB2YXIgPSBuaWwgIyB0ZW1wDQogICAgICBpbnN0YW5jZV92YXJpYWJs ZXMoKS5lYWNoIHsgfHZhcnwNCiAgICAgICAgdmFyID1+IC9eQCAoXHcrKSAkL3gNCiAgICAg ICAgYXNzZXJ0KCAkMSApDQogICAgICAgIGhbJDFdID0gaW5zdGFuY2VfdmFyaWFibGVfZ2V0 KHZhcikNCiAgICAgIH0jIGVhY2gNCg0KICAgICAgcmV0dXJuIGgNCiAgICBlbmQjIHRvX2go KQ0KICBlbmQjIFN0YWNrRnJhbWUNCg0KICAjICoqKioqKioqKioqKioqKiBDQUxMU1RBQ0sg KioqKioqKioqKioqKioqDQogICMgQWN0dWFsbHkgYW4gQXJyYXksIG5vdCBhIFN0YWNrIHBy b3Blci4NCiAgY2xhc3MgQ2FsbFN0YWNrIDwgQXJyYXkNCiAgICBpbmNsdWRlIFRlc3Q6OlVu aXQ6OkFzc2VydGlvbnMNCiAgICByZXF1aXJlICdkYXRlJw0KDQogICAgQHZlcnNpb24gPSAn MC4wLjEnDQogICAgY2xhc3MgPDwgc2VsZg0KICAgICAgYXR0cl9yZWFkZXIgOnZlcnNpb24N CiAgICBlbmQNCg0KDQogICAgIyBDbGFzcyBpbnN0YW5jZSB2YXJzOg0KICAgIEBmcmFtZV9j bGFzcyA9IEJpbmRpbmc6OlN0YWNrRnJhbWUNCiAgICBAdHJhY2luZ19leGNlcHRpb24gPSAi eENhbGxTdGFjazogI3tEYXRlVGltZS5ub3cudG9fc30iLmludGVybigpDQogICAgY2xhc3Mg PDwgc2VsZg0KICAgICAgYXR0cl9hY2Nlc3NvciA6ZnJhbWVfY2xhc3MNCiAgICAgIGF0dHJf YWNjZXNzb3IgOnRyYWNpbmdfZXhjZXB0aW9uDQogICAgZW5kDQoNCiAgICAjIEN0b3I6IGNh bGxfc3RhY2soKSBwYXNzZXMgaXRzIGJpbmRpbmcgaGl0aGVyLCBpbiBjYXNlIHdlIG5lZWQg dG8gcmVhZCBsb2NhbHMgdGhlcmVmcm9tIChhIHV0aWxpdHkgZGV2aWNlKS4gIFJlYWQtb25s eSENCiAgICAjIE5vdGU6IEEgbnVsbCB2YWx1ZSBmb3IgY2FsbF9zdGFja19iaW5kaW5nIHdp bGwgeWllbGQgYW4gZW1wdHkgb2JqZWN0Lg0KICAgIGRlZiBpbml0aWFsaXplKCBjYWxsX3N0 YWNrX2JpbmRpbmcgPSBuaWwgKQ0KICAgICAgaWYoIGNhbGxfc3RhY2tfYmluZGluZyApDQog ICAgICAgIEBjYWxsX3N0YWNrX2JpbmRpbmcgPSBjYWxsX3N0YWNrX2JpbmRpbmcgIyBTdG9y ZSBmb3IgdXNlIGluIGNhbGwoKS4NCg0KICAgICAgICBwdXNoIFN0YWNrRnJhbWU6Om5ldygp ICMgRGlzcG9zYWJsZTogZWxpbWluYXRlZCBpbiByZXQoKS4NCiAgICAgIGVuZCMgaWYNCiAg ICAgICMgZWxzZSBlbXB0eQ0KICAgIGVuZCMgY3RvcigpDQoNCiAgICAjIGNhbGwoKTogUmVw ZWF0ZWRseSB1c2VkIGJ5IGNhbGxfc3RhY2soKSB0byBhZGQgZnJhbWVzIHRvIHRoZSBhcnJh eSAoaGVuY2UgdGhlIG5hbWUpLg0KICAgICMgWyBjbGFzcywgbWV0aG9kLCBiaW5kaW5nLCBm aWxlLCBsaW5lIF0NCiAgICBkZWYgY2FsbCggdHJhY2VfZXZlbnQsIHRyYWNlX2ZpbGUsIHRy YWNlX2xpbmUsIHRyYWNlX21ldGhvZCwgdHJhY2VfYmluZCwgdHJhY2Vfb2JqZWN0ICkNCiAg ICAgIGFzc2VydCggZXZhbCggImRlZmluZWQ/IGFDYWxsZXJzIiwgQGNhbGxfc3RhY2tfYmlu ZGluZyApID09ICdsb2NhbC12YXJpYWJsZScgKSAjIEVuc3VyZSB3ZSBoYXZlIHRoZSBwcm9w ZXIgbmFtZSBmb3IgbG9jdmFyIGluIGNhbGxfc3RhY2soKS4NCiAgICAgIGFDYWxsZXJzID0g ZXZhbCggImFDYWxsZXJzIiwgQGNhbGxfc3RhY2tfYmluZGluZyApICMgdGVtcCB0byBhdm9p ZCByZXBlYXQgZXZhbCgpIGNhbGxzDQoNCiAgICAgIHB1c2ggU3RhY2tGcmFtZTo6bmV3KCkN CiAgICAgICMgVGhlIG5hdHVyZSBvZiBzZXRfdHJhY2VfZnVuYygpIGlzIHRvIHJldHVybiB0 aGUgY2xhc3MgYW5kIG1ldGhvZCBuYW1lIGZvciB0aGUgKnByZXZpb3VzKiBzdGFjayBmcmFt ZS4NCiAgICAgIGF0KC0yKS5vYmplY3QgPSB0cmFjZV9vYmplY3QNCiAgICAgIGF0KC0yKS5t ZXRob2QgPSB0cmFjZV9tZXRob2QNCg0KICAgICAgbGFzdC5iaW5kaW5nID0gdHJhY2VfYmlu ZA0KICAgICAgYUNhbGxlcnMuZmlyc3QgPX4gL14gKCBbXHdcLl0rICkgOiAoIFxkKyApIFxE Ki94DQogICAgICBhc3NlcnQoICQxICYmICQyICkNCiAgICAgIGxhc3QuZmlsZSA9ICQxDQog ICAgICBsYXN0LmxpbmUgPSAkMg0KDQogICAgICByZXR1cm4gc2VsZg0KICAgIGVuZCMgY2Fs bCgpDQoNCiAgICAjIHJldCgpOiBDYWxsZWQgYWZ0ZXIgYWxsIGl0ZXJhdGlvbnMgYXJlIGZp bmlzaGVkLCBqdXN0IGJlZm9yZSB0aGUgQ2FsbFN0YWNrIGlzIHBhc3NlZCBiYWNrIHRvIHRo ZSBjbGllbnQuDQogICAgZGVmIHJldCgpDQogICAgICBzaGlmdCgpICMgUmVtb3ZlIHBsYWNl aG9sZGVyIGZpcnN0IGVsZW1lbnQuDQogICAgICBhc3NlcnQoIGxlbmd0aCA+IDAgKQ0KDQog ICAgICBhc3NlcnQoIGV2YWwoICJkZWZpbmVkPyBuQ291bnQiLCBAY2FsbF9zdGFja19iaW5k aW5nICkgPT0gJ2xvY2FsLXZhcmlhYmxlJyApICMgRW5zdXJlIHdlIGhhdmUgdGhlIHByb3Bl ciBuYW1lIGZvciBsb2N2YXIgaW4gY2FsbF9zdGFjaygpLg0KDQogICAgICAjIElmIHRoZSBm aW5hbCBmcmFtZSBpc24ndCBhdCBtYWluIHNjb3BlLCBkZXBlbmRpbmcgb24gdGhlIGFyZ3Vt ZW50cyB0byBjYWxsX3N0YWNrKCksIGl0J3MgYWxzbyBhIHBsYWNlaG9sZGVyIGFuZCBtdXN0 IGJlIHJlbW92ZWQ6DQogICAgICBpZiggZXZhbCggIm5Db3VudCIsIEBjYWxsX3N0YWNrX2Jp bmRpbmcgKSApDQogICAgICAgIHBvcCgpDQogICAgICBlbHNlDQogICAgICAgICMgRmxlc2gg b3V0IGZpbmFsIGVsZW1lbnQ6DQogICAgICAgIGxhc3Qub2JqZWN0ID0gJ21haW4nDQogICAg ICAgIGxhc3QubWV0aG9kID0gbmlsDQogICAgICBlbmQjIGlmDQoNCiAgICAgIHJldHVybiBz ZWxmDQogICAgZW5kIyByZXQoKQ0KICBlbmQjIENhbGxTdGFjaw0KDQogICMgKioqKioqKioq KioqKioqIENBTExfU1RBQ0sgKioqKioqKioqKioqKioqDQogICMgY2FsbF9zdGFjaygpOiBS ZXRyaWV2ZSBDYWxsU3RhY2sgb2JqZWN0IChhcnJheSBvZiBTdGFja0ZyYW1lIG9iamVjdHMp Lg0KICBkZWYgQmluZGluZzo6Y2FsbF9zdGFjayggblNraXBGcmFtZXMgPSAwLCBuQ291bnQg PSBuaWwgKQ0KICAgICMgVmFsaWRhdGUgdmFyczoNCiAgICBbblNraXBGcmFtZXMsIG5Db3Vu dF0uZWFjaCB7IHx2YXJ8DQogICAgICBpZiggdmFyICYmICghdmFyLmlzX2E/KEludGVnZXIp IHx8ICh2YXIgPCAwICkpICkgdGhlbiByYWlzZSggQXJndW1lbnRFcnJvciwgIk9wdGlvbmFs IGFyZ3VtZW50IHRvIGNhbGxfc3RhY2soKSBzaG91bGQgYmUgYSBub25uZWdhdGl2ZSBJbnRl Z2VyLiIgKTsgZW5kDQogICAgfSMgZWFjaA0KDQogICAgIyBTdG9yZSB0ZW1wb3JhcmlseSB0 byBvYnZpYXRlIHJlaW52b2NhdGlvbi4gIE5lZWRlZCBiZWxvdywgYW5kIGFsc28gYnkgdGhl IGN1cnJlbnQgaW1wbGVtZW50YXRpb24gb2YgY2xhc3MgQ2FsbFN0YWNrLCBzbyBJIG9wdGVk IHRvIHN0b3JlIGl0IGhlcmUgYW5kIHBhc3MgdGhlIENhbGxTdGFjayBjdG9yIHRoaXMsIGNh bGxfc3RhY2soKSdzLCBiaW5kaW5nLCB0byBhbGxvdyBmb3IgZ3JlYXRlciBmbGV4aWJpbGl0 eSBpZiBDYWxsU3RhY2sgaXMgZXh0ZW5kZWQuDQogICAgYUNhbGxlcnMgPSBjYWxsZXIoKQ0K DQogICAgIyBJZiBhdCB0b3BsZXZlbCBvciBuU2tpcEZyYW1lcyBpcyBncmVhdGVyIHRoYW4g dGhlIG51bWJlciBvZiBmcmFtZXMgYXZhaWxhYmxlLCAvb3IvIHRoZSBjbGllbnQgZXhwbGlj aXRseSByZXF1ZXN0cyB6ZXJvIGZyYW1lcywgZXhpdCBlYXJseToNCiAgICBpZiggKGFDYWxs ZXJzLmxlbmd0aC1uU2tpcEZyYW1lcyA8PSAwKSB8fCAobkNvdW50ID09IDApICkgdGhlbiBy ZXR1cm4gQmluZGluZzo6c3RhY2tfY2xhc3M6Om5ldygpOyBlbmQNCg0KICAgICMgVHJpbSB0 aGUgZmlyc3QgZW50cnksIHRoZSBjbGllbnQgZnVuY3Rpb24sIHdoaWNoIHdlIGRvbid0IHdh bnQgdG8gaW5jbHVkZTsgdGhlbiBvbWl0IHRoZSBuZXh0IG5Ta2lwRnJhbWVzIGVudHJpZXMu DQoNCiAgICAjIElmIG5Db3VudCBzdWZmaWNpZW50bHkgbGFyZ2UsIG5vIHJlYXNvbiB0byB1 c2UgaXQgYXQgYWxsOg0KICAgIGlmKCBuQ291bnQgJiYgKCBuU2tpcEZyYW1lcytuQ291bnQg Pj0gYUNhbGxlcnMubGVuZ3RoKSApIHRoZW4gbkNvdW50ID0gbmlsOyBlbmQNCg0KICAgICMg VHJpbSBlbmQgaWYgbkNvdW50IHByb3ZpZGVkOg0KICAgIGlmKCBuQ291bnQgKQ0KICAgICAg YXNzZXJ0KCBuQ291bnQgPCBhQ2FsbGVycy5sZW5ndGggKQ0KICAgICAgbkNvdW50ICs9IG5T a2lwRnJhbWVzKzEgIyBJZiBuQ291bnQgbXVzdCBiZSB1c2VkIGluIGl0cyAicHJvcGVyIiBm dW5jdGlvbiwgd2UgaGF2ZSB0byBwYWQgb3V0IHRoZSBudW1iZXIgb2YgdHJhY2UgY2FsbHMg dG8gb25lIGJleW9uZCB0aGUgc3BlY2lmaWVkLCBpbiBvcmRlciB0byByZWNlaXZlIG9iamVj dCBhbmQgbWV0aG9kIGluZm8gKHNlZSBDYWxsU3RhY2s6OmNhbGwoKSwgYWJvdmUpLg0KICAg ICAgYUNhbGxlcnMuc2xpY2UhKG5Db3VudCAuLiAtMSkNCiAgICBlbmQjIGVuZA0KDQogICAg YUNhbGxTdGFjayA9IEJpbmRpbmc6OnN0YWNrX2NsYXNzOjpuZXcoIGJpbmRpbmcoKSApICMg UGFzcyBjdXJyZW50IEJpbmRpbmcsIGdpdmluZyBDYWxsU3RhY2sgYWNjZXNzIHRvIGxvY2Fs cy4NCiAgICBjYWxsY2MgeyB8Y2N8DQogICAgICAjIEhvcGUgc3ByaW5ncyBldGVybmFsKCEp Og0KICAgICAgI29sZF90cmFjZWZ1bmMgPSBnZXRfdHJhY2VfZnVuYygpDQogICAgICBzZXRf dHJhY2VfZnVuYygNCiAgICAgICAgcHJvYyB7DQogICAgICAgICAgIyBldmVudCwgZmlsZSwg bGluZSwgaWQsIGJpbmQsIGNsYXNzbmFtZQ0KICAgICAgICAgIHxldmVudCwgKnJlbWFpbmlu Z19hcmdzfA0KDQogICAgICAgICAgaWYoIGV2ZW50ID09ICdyZXR1cm4nICkNCiAgICAgICAg ICAgICMgSWYgZnJhbWUgY2FwdHVyZSB5ZXQgZW5hYmxlZDoNCiAgICAgICAgICAgIGlmKCBu U2tpcEZyYW1lcyA9PSAwICkNCiAgICAgICAgICAgICAgIyBjYXB0dXJlIGN1cnJlbnQ6DQog ICAgICAgICAgICAgIGFDYWxsU3RhY2suY2FsbCggZXZlbnQsICpyZW1haW5pbmdfYXJncyAp DQogICAgICAgICAgICBlbHNlICMgc2tpcCB0byBuZXh0DQogICAgICAgICAgICAgIG5Ta2lw RnJhbWVzIC09IDENCiAgICAgICAgICAgIGVuZCMgaWYNCg0KICAgICAgICAgICAgYUNhbGxl cnMuc2hpZnQoKQ0KDQogICAgICAgICAgICAjIElmIGF0IHRvcGxldmVsLCBlbmQgcmlkZToN CiAgICAgICAgICAgIGlmKCBhQ2FsbGVycy5sZW5ndGggPT0gMCApDQogICAgICAgICAgICAg ICNzZXRfdHJhY2VfZnVuYyggZ2V0X3RyYWNlX2Z1bmMoKSApDQogICAgICAgICAgICAgIHNl dF90cmFjZV9mdW5jKCBuaWwgKQ0KDQogICAgICAgICAgICAgICMgLS0tLS0+IFN0YWNrIHVu cm9sbGluZyBmaW5pc2hlcyBoZXJlOg0KICAgICAgICAgICAgICBjYy5jYWxsKCkNCiAgICAg ICAgICAgIGVuZCMgaWYNCiAgICAgICAgICBlbmQjIGlmDQogICAgICAgIH0jIHByb2MNCiAg ICAgICkjIHNldF90cmFjZV9mdW5jDQoNCiAgICAgICMgU3RhY2sgdW5yb2xsaW5nIGJlZ2lu cyBoZXJlOiAtLS0tLT4NCiAgICAgIHRocm93KCBCaW5kaW5nOjpDYWxsU3RhY2s6OnRyYWNp bmdfZXhjZXB0aW9uICkNCiAgICB9IyBjYWxsY2MNCg0KICAgIGFzc2VydChuU2tpcEZyYW1l cykNCg0KICAgICMgUmVzdW1lIGV4ZWN1dGlvbiBpbiBjbGllbnQgZnVuYzoNCiAgICBhQ2Fs bFN0YWNrLnJldCgpDQogICAgcmV0dXJuKCBhQ2FsbFN0YWNrICkNCiAgZW5kIyBjYWxsX3N0 YWNrKCkNCg0KICAjIENsYXNzIGluc3RhbmNlIHZhcjoNCiAgQHN0YWNrX2NsYXNzID0gQmlu ZGluZzo6Q2FsbFN0YWNrDQogIGNsYXNzIDw8IHNlbGYNCiAgICBhdHRyX2FjY2Vzc29yIDpz dGFja19jbGFzcw0KICBlbmQNCmVuZCMgQmluZGluZw0K --------------050605030406090106090309 Content-Type: application/x-ruby; name="call_stack_test.rb" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="call_stack_test.rb" cmVxdWlyZSAnY2FsbF9zdGFjaycNCg0KZGVmIHgoKQ0KICBiZWdpbg0KICAgIGNvbnRleHQg PSBCaW5kaW5nLmNhbGxfc3RhY2suZmlyc3QuYmluZGluZw0KICAgICMgLi4uIGNsZXZlciBo YWNrZXJ5IGdvZXMgaGVyZSAuLi4NCiAgZW5zdXJlDQogICAgcHV0cyAiVGhpcyBzaG91bGQg b25seSBiZSBleGVjdXRlZCBvbmNlLiINCiAgZW5kDQplbmQNCg0KeCgp --------------050605030406090106090309--