On Fri, Nov 28, 2008 at 8:52 AM, Bert Freudenberg <[hidden email]> wrote:
In terms of code smells, this is chemical warfare!! :-D. Gulik. -- http://people.squeakfoundation.org/person/mikevdg http://gulik.pbwiki.com/ |
In reply to this post by Bert Freudenberg
Bert Freudenberg a écrit :
> > On 27.11.2008, at 18:44, Keith Hodges wrote: > >> Hello All, >> >> I need a villainous superpower that I haven't needed before, can anyone >> tell me how to achieve this. >> >> I have some code like this: >> >> self send a message to me. >> self nextThing. >> >> or >> >> self send a message to me. >> A := self nextThing. >> >> What naughty superpower code can I put in to #send that will jump >> execution to self nextThing directly? > > > send > ... > thisContext sender jump: 4 > > This skips 4 bytecodes in the calling method before returning, so > instead of pc=31 it continues at pc=35: > > 29 <70> self > 30 <D4> send: send > 31 <D3> send: a > 32 <D2> send: message > 33 <D1> send: to > 34 <D0> send: me > 35 <87> pop > 36 <70> self > 37 <D5> send: nextThing > 38 <87> pop > 39 <78> returnSelf > > - Bert - > > Maybe something like a classical doesNotUnderstand: handling... A SilentMessageAbsorber could return self if it doesNotUnderstand: a message, so implement send ^SilentMessageAbsorber new That's not exactly direct, rather nop... Nicolas |
In reply to this post by Michael van der Gulik-2
On 27.11.2008, at 21:52, Michael van der Gulik wrote:
>> On Fri, Nov 28, 2008 at 8:52 AM, Bert Freudenberg <[hidden email] >> > wrote: >> >>> On 27.11.2008, at 18:44, Keith Hodges wrote: >>> >>> Hello All, >>> >>> I need a villainous superpower that I haven't needed before, can >>> anyone >>> tell me how to achieve this. >>> >>> I have some code like this: >>> >>> self send a message to me. >>> self nextThing. >>> >>> or >>> >>> self send a message to me. >>> A := self nextThing. >>> >>> What naughty superpower code can I put in to #send that will jump >>> execution to self nextThing directly? >> >> >> send >> ... >> thisContext sender jump: 4 >> >> This skips 4 bytecodes in the calling method before returning, so >> instead of pc=31 it continues at pc=35: >> > > In terms of code smells, this is chemical warfare!! :-D. No doubt about this. Kids, don't try this at home. It still tremendous fun that you can do it. Keith, I have no idea what you need this for but I think the following is pretty complete - it skips until the next pop bytecode which marks the end of the current statement. It should get confused only if there was a block in that line that had a pop in itself: send Transcript show: 'send '. self returnToPop. self neverReached returnToPop | ctxt | ctxt := thisContext sender sender. [ctxt nextByte = 135] whileFalse: [ctxt jump: 1]. ctxt resume Try filing in attachment and eval "Evil new test" - Bert - Evil.st (1K) Download Attachment |
>> >> In terms of code smells, this is chemical warfare!! :-D. I must admit I am having second thoughts! > No doubt about this. Kids, don't try this at home. > > It still tremendous fun that you can do it. Keith, I have no idea what > you need this for but I think the following is pretty complete - it > skips until the next pop bytecode which marks the end of the current > statement. It should get confused only if there was a block in that > line that had a pop in itself: > > send > Transcript show: 'send '. > self returnToPop. > self neverReached > > returnToPop > | ctxt | > ctxt := thisContext sender sender. > [ctxt nextByte = 135] > whileFalse: [ctxt jump: 1]. > ctxt resume > > Try filing in attachment and eval "Evil new test" > > - Bert - we can do it. In the Logging framework, the message eating Null WAS used to disable logging features. so for example the call... self log info mysql dumper: theDataReturned asSuitableFormat. A) to disable the #info level log messages -> MyLogRouterPolicy-#info ^null B) to disable the #mysql category log messages -> MyLogRouterPolicy-#mysql ^null C) to disable all Logging, and even remove the Logging framework completely. Object-#log ^null Realizing that some user code may take a lot of time, #asSuitableFormat in this example, I began looking for alternative solutions. (hence the question) Instead of using null as a hammer, I implemented an explicit #isIgnore flag which covers most use cases. (It still cannot cover the case where no Logging framework is loaded at all) My solution is as follows: self log info mysql use: [ self log dumper: theDataReturned asSuitableFormat ]. I have a personal convention #use: is my version of #in: which is a bit more flexible, I use it like this e.g. To ensure streams close: FileStream-#use: ^ [ aBlock value: self ] ensure: [ self close ]. To provide psuedo null behaviour (equivalent of ifNotNilDo:) UndefinedObject-#use: aBlock ^ self So... LogRouter-#use: aBlock isIgnore ifFalse: [ aBlock value ] This allows a user to disable mysql Logging by implementing MyLogRouterPolicy-#mysql ^ self ignore With this solution I am almost happy. It is cleaner, and allows whole chunks of logging code to be skipped if the user simply sets part of their LoggingPolicy to self ignore. So, we can now spit chunks of verbose logging code without being afraid of slowing things down for someone else, since we know that any user is in complete control via their chosen LogRouterPolicy However, after this I dont think I can resist releasing "SuperNull" sometime soon. thanks for an interesting insight, Keith |
2008/11/28 Keith Hodges <[hidden email]>:
> >>> >>> In terms of code smells, this is chemical warfare!! :-D. > I must admit I am having second thoughts! >> No doubt about this. Kids, don't try this at home. >> >> It still tremendous fun that you can do it. Keith, I have no idea what >> you need this for but I think the following is pretty complete - it >> skips until the next pop bytecode which marks the end of the current >> statement. It should get confused only if there was a block in that >> line that had a pop in itself: >> >> send >> Transcript show: 'send '. >> self returnToPop. >> self neverReached >> >> returnToPop >> | ctxt | >> ctxt := thisContext sender sender. >> [ctxt nextByte = 135] >> whileFalse: [ctxt jump: 1]. >> ctxt resume >> >> Try filing in attachment and eval "Evil new test" >> >> - Bert - > Thats really cool, thanks! It gives me a warm fuzzy feeling just to know > we can do it. > > In the Logging framework, the message eating Null WAS used to disable > logging features. > > so for example the call... > > self log info mysql dumper: theDataReturned asSuitableFormat. > > A) to disable the #info level log messages -> MyLogRouterPolicy-#info ^null > B) to disable the #mysql category log messages -> > MyLogRouterPolicy-#mysql ^null > C) to disable all Logging, and even remove the Logging framework > completely. Object-#log ^null > > Realizing that some user code may take a lot of time, #asSuitableFormat > in this example, I began looking for alternative solutions. (hence the > question) > > Instead of using null as a hammer, I implemented an explicit #isIgnore > flag which covers most use cases. (It still cannot cover the case where > no Logging framework is loaded at all) > > My solution is as follows: > > self log info mysql use: [ > > self log dumper: theDataReturned asSuitableFormat > > ]. > > I have a personal convention #use: is my version of #in: which is a bit > more flexible, I use it like this e.g. > > To ensure streams close: > > FileStream-#use: ^ [ aBlock value: self ] ensure: [ self close ]. > > To provide psuedo null behaviour (equivalent of ifNotNilDo:) > > UndefinedObject-#use: aBlock ^ self > > So... > > LogRouter-#use: aBlock > > isIgnore ifFalse: [ aBlock value ] > > This allows a user to disable mysql Logging by implementing > > MyLogRouterPolicy-#mysql ^ self ignore > > With this solution I am almost happy. It is cleaner, and allows whole > chunks of logging code to be skipped if the user simply sets part of > their LoggingPolicy to self ignore. > > So, we can now spit chunks of verbose logging code without being afraid > of slowing things down for someone else, since we know that any user is > in complete control via their chosen LogRouterPolicy > > However, after this I dont think I can resist releasing "SuperNull" > sometime soon. > > thanks for an interesting insight, > > Keith > > A shorter form of: self log info mysql use: [ self log dumper: theDataReturned asSuitableFormat ]. Could be: self log info mysql dump: [ theDataReturned asSuitableFormat ] -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |