[squeak-dev] Files documentation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: How to do logging (was Re: [squeak-dev] Files documentation)

Michael van der Gulik-2


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.

Gulik.

--
http://people.squeakfoundation.org/person/mikevdg
http://gulik.pbwiki.com/


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: How to do logging (was Re: Files documentation)

Nicolas Cellier-3
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


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Villainous superpowers (Re: How to do logging)

Bert Freudenberg
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
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Villainous superpowers (Re: How to do logging)

keith1y
 
>>
>> 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








Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Villainous superpowers (Re: How to do logging)

Igor Stasenko
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.

12