How to capture the execution of a playground?

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

How to capture the execution of a playground?

Offray Vladimir Luna Cárdenas-2
Hi,

I would like to store the object resulting from executing a playground.
This would imply two steps:

- Knowing that the playground content was executed (via the play button
or its shortcuts Ctrl + Shift + g or Ctrl + g).
- Getting the results of that execution. For example if the result at
the end is a string or a dictionary, I would like to get that string or
dictionary.

Any pointers on how to make that will be welcomed.

Cheers,

Offray

Ps: I still get lost when I search by myself trying to answer questions
like the ones above. I imagine that in some way is related with
evaluationAction and presentations, by looking for the source code of
"do it and go", but still I can't get a functional code snippet to start
prototyping.

Reply | Threaded
Open this post in threaded view
|

Re: How to capture the execution of a playground?

Ben Coman


On Tue, Feb 28, 2017 at 11:28 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:
Hi,

I would like to store the object resulting from executing a playground. This would imply two steps:

- Knowing that the playground content was executed (via the play button or its shortcuts Ctrl + Shift + g or Ctrl + g).
- Getting the results of that execution. For example if the result at the end is a string or a dictionary, I would like to get that string or dictionary.

Any pointers on how to make that will be welcomed.

Cheers,

Offray

Ps: I still get lost when I search by myself trying to answer questions like the ones above. I imagine that in some way is related with evaluationAction and presentations, by looking for the source code of "do it and go", but still I can't get a functional code snippet to start prototyping.


In playground, if you evaluate "self halt. 42" at top of the debug stack you'll see method...
   Undefined>>DoIt   
       self halt.
       ^ 42

where stepping 
OVER returns 42 into "value" variable in OpalCompiler>>evaluate
OVER returns 42 into "result" variable in RubSmalltalkEditor>>evaluate:andDo:
at the end of which stepping 
INTO "^aBlock value: result"  takes you to RubSmalltalkEditor>>highlightEvaluateAndDo:, where
INTO "[:result | aBlock value: result]"    takes you to GLMPharoScriptPResentation(GLMRubricSmalltalkCodePresentation)>>executionSelectionActions
where changing "aPresentation highlightEvaluateAndDo: [ :result | ] ]; 
                      to "aPresentation highlightEvaluateAndDo: [ :result | self inform: 'Result ' , result printString] ]; "
   and opening a new Playground, then evaluating "42" informs us that 42 is the result.

Stepping further along, in GLMMorphicPharoScriptRenderer(GLMMorphicPharoCodePresentation)>>highlightEvaluateAndDo:: 
the value returned from...
    self 
  evaluate: self highlightedTextAsStream
  andDo: [:result | aBlock value: result. ].

is not 42 but aGLMPharoScriptPresentation.  it might help to change that to... 
  andDo: [:result | aBlock value: result.  result ].
but anyway that return value is thrown away in GLMMorphicPharoScriptRenderer(GLMMorphicPharoCodePresentation)>>actOnHighlightAndEvaluate:


So subclassing GLMRubricSmalltalkCodePresentation and overriding #executionSelectionActions
is perhaps your best bet.  Or some GLM expert provides a nice way for a user to set this customAssignmentBlock...
      aPresentation highlightEvaluateAndDo: [ :result | customAssignmentBlock value: result ]. 
in #executionSelectionActions.

cheers -ben

Reply | Threaded
Open this post in threaded view
|

Re: How to capture the execution of a playground?

Ben Coman


On Tue, Feb 28, 2017 at 3:12 PM, Ben Coman <[hidden email]> wrote:


On Tue, Feb 28, 2017 at 11:28 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:
Hi,

I would like to store the object resulting from executing a playground. This would imply two steps:

- Knowing that the playground content was executed (via the play button or its shortcuts Ctrl + Shift + g or Ctrl + g).
- Getting the results of that execution. For example if the result at the end is a string or a dictionary, I would like to get that string or dictionary.

Any pointers on how to make that will be welcomed.

Cheers,

Offray

Ps: I still get lost when I search by myself trying to answer questions like the ones above. I imagine that in some way is related with evaluationAction and presentations, by looking for the source code of "do it and go", but still I can't get a functional code snippet to start prototyping.


In playground, if you evaluate "self halt. 42" at top of the debug stack you'll see method...
   Undefined>>DoIt   
       self halt.
       ^ 42

where stepping 
OVER returns 42 into "value" variable in OpalCompiler>>evaluate
OVER returns 42 into "result" variable in RubSmalltalkEditor>>evaluate:andDo:
at the end of which stepping 
INTO "^aBlock value: result"  takes you to RubSmalltalkEditor>>highlightEvaluateAndDo:, where
INTO "[:result | aBlock value: result]"    takes you to GLMPharoScriptPResentation(GLMRubricSmalltalkCodePresentation)>>executionSelectionActions
where changing "aPresentation highlightEvaluateAndDo: [ :result | ] ]; 
                      to "aPresentation highlightEvaluateAndDo: [ :result | self inform: 'Result ' , result printString] ]; "
   and opening a new Playground, then evaluating "42" informs us that 42 is the result.

Stepping further along, in GLMMorphicPharoScriptRenderer(GLMMorphicPharoCodePresentation)>>highlightEvaluateAndDo:: 
the value returned from...
    self 
  evaluate: self highlightedTextAsStream
  andDo: [:result | aBlock value: result. ].

is not 42 but aGLMPharoScriptPresentation.  it might help to change that to... 
  andDo: [:result | aBlock value: result.  result ].
but anyway that return value is thrown away in GLMMorphicPharoScriptRenderer(GLMMorphicPharoCodePresentation)>>actOnHighlightAndEvaluate:


So subclassing GLMRubricSmalltalkCodePresentation and overriding #executionSelectionActions
is perhaps your best bet.  Or some GLM expert provides a nice way for a user to set this customAssignmentBlock...
      aPresentation highlightEvaluateAndDo: [ :result | customAssignmentBlock value: result ]. 
in #executionSelectionActions.

cheers -ben


>> Ps: I still get lost when I search by myself trying to answer questions like the ones above. I imagine that in some way is related with evaluationAction and presentations, by looking for the source code of "do it and go", but still I can't get a functional code snippet to start prototyping.

btw, I didn't know any of that 10 minutes ago.  I find it hard to answer such questions looking at static code. The trick is finding the right place to drop a "haltOnce" so you can observe the flow of live objects. Prospective breakpoints generally come from peeking behind menus and button using halos, or searching for their label strings using Tools > Finder >> Source.  In this case it was easier since I knew the DoIt was compiled into code that returned the result and could just trace that flow through.

cheers -ben
Reply | Threaded
Open this post in threaded view
|

Re: How to capture the execution of a playground?

Offray Vladimir Luna Cárdenas-2
In reply to this post by Ben Coman

On 28/02/17 02:12, Ben Coman wrote:


On Tue, Feb 28, 2017 at 11:28 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:
Hi,

I would like to store the object resulting from executing a playground. This would imply two steps:

- Knowing that the playground content was executed (via the play button or its shortcuts Ctrl + Shift + g or Ctrl + g).
- Getting the results of that execution. For example if the result at the end is a string or a dictionary, I would like to get that string or dictionary.

Any pointers on how to make that will be welcomed.

Cheers,

Offray

Ps: I still get lost when I search by myself trying to answer questions like the ones above. I imagine that in some way is related with evaluationAction and presentations, by looking for the source code of "do it and go", but still I can't get a functional code snippet to start prototyping.


In playground, if you evaluate "self halt. 42" at top of the debug stack you'll see method...
   Undefined>>DoIt   
       self halt.
       ^ 42

where stepping 
OVER returns 42 into "value" variable in OpalCompiler>>evaluate
OVER returns 42 into "result" variable in RubSmalltalkEditor>>evaluate:andDo:
at the end of which stepping 
INTO "^aBlock value: result"  takes you to RubSmalltalkEditor>>highlightEvaluateAndDo:, where
INTO "[:result | aBlock value: result]"    takes you to GLMPharoScriptPResentation(GLMRubricSmalltalkCodePresentation)>>executionSelectionActions

Wow that was pretty insightful! Thanks Ben. I still don't know when to use Over or Into, but that idea of inserting a halt in a playground to inspect behavior from them is really powerful.



where changing "aPresentation highlightEvaluateAndDo: [ :result | ] ]; 
                      to "aPresentation highlightEvaluateAndDo: [ :result | self inform: 'Result ' , result printString] ]; "
   and opening a new Playground, then evaluating "42" informs us that 42 is the result.


Yes, that captures and informs the result of the playground. Something similar happens when I change GLMPharoScriptPresentation>>goAction with:

action: [ :t :entity |
                    t highlightEvaluateAndDo: [ :result | t selection: result. self inform: 'Result ' , result printString ] ];

So, I'm able now to capture the result of a code execution in a playground (a partial selection or the full code)

Stepping further along, in GLMMorphicPharoScriptRenderer(GLMMorphicPharoCodePresentation)>>highlightEvaluateAndDo:: 
the value returned from...
    self 
  evaluate: self highlightedTextAsStream
  andDo: [:result | aBlock value: result. ].

is not 42 but aGLMPharoScriptPresentation.  it might help to change that to... 
  andDo: [:result | aBlock value: result.  result ].
but anyway that return value is thrown away in GLMMorphicPharoScriptRenderer(GLMMorphicPharoCodePresentation)>>actOnHighlightAndEvaluate:


So subclassing GLMRubricSmalltalkCodePresentation and overriding #executionSelectionActions
is perhaps your best bet.  Or some GLM expert provides a nice way for a user to set this customAssignmentBlock...
      aPresentation highlightEvaluateAndDo: [ :result | customAssignmentBlock value: result ]. 
in #executionSelectionActions.


Yes, I would expect a more "user friendly" way to do it. Something related with playground announcements to know when the play button has been executed and how the resulting object of this particular action is showed in the resulting pane. Is there a possibility like this?

Cheers,

Offray
Reply | Threaded
Open this post in threaded view
|

Re: How to capture the execution of a playground?

Ben Coman


On Wed, Mar 1, 2017 at 10:06 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:

On 28/02/17 02:12, Ben Coman wrote:


On Tue, Feb 28, 2017 at 11:28 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:
Hi,

I would like to store the object resulting from executing a playground. This would imply two steps:

- Knowing that the playground content was executed (via the play button or its shortcuts Ctrl + Shift + g or Ctrl + g).
- Getting the results of that execution. For example if the result at the end is a string or a dictionary, I would like to get that string or dictionary.

Any pointers on how to make that will be welcomed.

Cheers,

Offray

Ps: I still get lost when I search by myself trying to answer questions like the ones above. I imagine that in some way is related with evaluationAction and presentations, by looking for the source code of "do it and go", but still I can't get a functional code snippet to start prototyping.


In playground, if you evaluate "self halt. 42" at top of the debug stack you'll see method...
   Undefined>>DoIt   
       self halt.
       ^ 42

where stepping 
OVER returns 42 into "value" variable in OpalCompiler>>evaluate
OVER returns 42 into "result" variable in RubSmalltalkEditor>>evaluate:andDo:
at the end of which stepping 
INTO "^aBlock value: result"  takes you to RubSmalltalkEditor>>highlightEvaluateAndDo:, where
INTO "[:result | aBlock value: result]"    takes you to GLMPharoScriptPResentation(GLMRubricSmalltalkCodePresentation)>>executionSelectionActions

Wow that was pretty insightful! Thanks Ben. I still don't know when to use Over or Into,

It helps to observe the three types of stepping behavior side by side.
I've devised a little demo.

First, to help keep track of the windows, hack this mod into RubSmalltalkEditor>>debug:receiver:in: 
    debugSession := guineaPig newDebugSessionNamed: ('debug ' , aCompiledMethod selector printString asUppercase)  startedAt: context.

In playground evaluate...
   Object subclass: #DebugDemo
instanceVariableNames: ''
classVariableNames: ''
package: 'DebugDemo'.

In playground evaluate...
    #('over' 'through' 'into') do: [ :demoMethodName| 
DebugDemo compile: demoMethodName , '
            x := 0.
            #(1 2) do: [:n | x := x + 1].
            self inform: x printString.'.
            RubSmalltalkEditor new debug: (DebugDemo>>(demoMethodName asSymbol)) receiver: nil in: nil.
].

Arrange the three debug windows side by side, left to right, OVER, THROUGH, INTO.


1. Moving left to right, click once on each window's related "step" button - OVER then THROUGH then INTO.
    While views remain the same, repeat 1.

2. When views diverge, keep clicking INTO until it matches THROUGH.

3. While THROUGH and INTO views remain the same, keep alternately clicking these.
    When they diverge return to 2. 
    When all views are the same, return to 1.

The key thing to observe with the INTO window, is that sending #value: to the array gets you to the same place as THROUGH got in one step. It skips through the block support infrastructure.

i think maybe it would help to rearrange the "step" buttons in order of increasing detail. i.e. OVER, THROUGH, INTO.
Also maybe the "through" icon could be a right arrow inside square brackets like this... [-->].
That would probably look neater without the underline.


To put the terminology into perspective, I've contrived a poor analogy of...
A method being a path along the ground. 
Each slab is a message send.  Under each slab is an offshoot tunnel with further slabs along it.

The quickest way down the path is to step OVER each slab(message send) because you don't care what is happening beneath the slab.

Sometimes you need to know everything that is going on underneath, so you lift up the slab and go INTO the tunnel and step on each of the slabs in the tunnel.

Now to stretch the analogy, consider that a block is held at the end #do: tunnel.  You are interested in the individual steps of the block, but not in all the steps of the tunnel (which is the support infrastructure that iterates a collection sending #value: to each element), so you fly THROUGH the tunnel without touching the individual steps, and just step the slabs of the block held at the end. Phew!

So in summary,
INTO steps into every message send.
OVER and THROUGH are similar, but the first steps over blocks, and the latter steps through blocks. 

HTH,
cheers -ben




Reply | Threaded
Open this post in threaded view
|

Re: How to capture the execution of a playground?

philippeback
You can see what's going on with this:

p := GTPlayground open.
pmodel := p model.
logger := GLMMemoryLogger new.
pmodel logger: logger.
pmodel

Then open the annoucements pane to see what is going on.

Be ready to use the interrupt combo as I have experienced strange effects :-)

If you have a handle on the model, you can see a lot.

Somewhere one can find the bindings, which can then be persisted to disk, STON comes to mind.

HTH

Phil

On Wed, Mar 1, 2017 at 5:45 AM, Ben Coman <[hidden email]> wrote:


On Wed, Mar 1, 2017 at 10:06 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:

On 28/02/17 02:12, Ben Coman wrote:


On Tue, Feb 28, 2017 at 11:28 AM, Offray Vladimir Luna Cárdenas <[hidden email]> wrote:
Hi,

I would like to store the object resulting from executing a playground. This would imply two steps:

- Knowing that the playground content was executed (via the play button or its shortcuts Ctrl + Shift + g or Ctrl + g).
- Getting the results of that execution. For example if the result at the end is a string or a dictionary, I would like to get that string or dictionary.

Any pointers on how to make that will be welcomed.

Cheers,

Offray

Ps: I still get lost when I search by myself trying to answer questions like the ones above. I imagine that in some way is related with evaluationAction and presentations, by looking for the source code of "do it and go", but still I can't get a functional code snippet to start prototyping.


In playground, if you evaluate "self halt. 42" at top of the debug stack you'll see method...
   Undefined>>DoIt   
       self halt.
       ^ 42

where stepping 
OVER returns 42 into "value" variable in OpalCompiler>>evaluate
OVER returns 42 into "result" variable in RubSmalltalkEditor>>evaluate:andDo:
at the end of which stepping 
INTO "^aBlock value: result"  takes you to RubSmalltalkEditor>>highlightEvaluateAndDo:, where
INTO "[:result | aBlock value: result]"    takes you to GLMPharoScriptPResentation(GLMRubricSmalltalkCodePresentation)>>executionSelectionActions

Wow that was pretty insightful! Thanks Ben. I still don't know when to use Over or Into,

It helps to observe the three types of stepping behavior side by side.
I've devised a little demo.

First, to help keep track of the windows, hack this mod into RubSmalltalkEditor>>debug:receiver:in: 
    debugSession := guineaPig newDebugSessionNamed: ('debug ' , aCompiledMethod selector printString asUppercase)  startedAt: context.

In playground evaluate...
   Object subclass: #DebugDemo
instanceVariableNames: ''
classVariableNames: ''
package: 'DebugDemo'.

In playground evaluate...
    #('over' 'through' 'into') do: [ :demoMethodName| 
DebugDemo compile: demoMethodName , '
            x := 0.
            #(1 2) do: [:n | x := x + 1].
            self inform: x printString.'.
            RubSmalltalkEditor new debug: (DebugDemo>>(demoMethodName asSymbol)) receiver: nil in: nil.
].

Arrange the three debug windows side by side, left to right, OVER, THROUGH, INTO.


1. Moving left to right, click once on each window's related "step" button - OVER then THROUGH then INTO.
    While views remain the same, repeat 1.

2. When views diverge, keep clicking INTO until it matches THROUGH.

3. While THROUGH and INTO views remain the same, keep alternately clicking these.
    When they diverge return to 2. 
    When all views are the same, return to 1.

The key thing to observe with the INTO window, is that sending #value: to the array gets you to the same place as THROUGH got in one step. It skips through the block support infrastructure.

i think maybe it would help to rearrange the "step" buttons in order of increasing detail. i.e. OVER, THROUGH, INTO.
Also maybe the "through" icon could be a right arrow inside square brackets like this... [-->].
That would probably look neater without the underline.


To put the terminology into perspective, I've contrived a poor analogy of...
A method being a path along the ground. 
Each slab is a message send.  Under each slab is an offshoot tunnel with further slabs along it.

The quickest way down the path is to step OVER each slab(message send) because you don't care what is happening beneath the slab.

Sometimes you need to know everything that is going on underneath, so you lift up the slab and go INTO the tunnel and step on each of the slabs in the tunnel.

Now to stretch the analogy, consider that a block is held at the end #do: tunnel.  You are interested in the individual steps of the block, but not in all the steps of the tunnel (which is the support infrastructure that iterates a collection sending #value: to each element), so you fly THROUGH the tunnel without touching the individual steps, and just step the slabs of the block held at the end. Phew!

So in summary,
INTO steps into every message send.
OVER and THROUGH are similar, but the first steps over blocks, and the latter steps through blocks. 

HTH,
cheers -ben