[squeak-dev] Resume Problems

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

[squeak-dev] Resume Problems

Zulq Alam-2
Hi All,

Perhaps I am misunderstanding the behaviour of

I have a class SoupTag which holds a dictionary of attributes and a
collection of children which are also soup tags.

As a shorthand for attribute access, SoupTag implements:

SoupTag>>doesNotUnderstand: aMessage
     (aMessage arguments size = 0)
         ifFalse: [^ super doesNotUnderstand: aMessage].
     ^ attributes
         at: aMessage selector
         ifAbsent: [super doesNotUnderstand: aMessage]

So that a SoupTag with attribute id=100 would answer 100 to #id and DNU
to any other selector. This seems to work fine but I'm having trouble
implementing a flexible find: method. The test case is

tag := SoupTag new
tag attributeAt: 'id' put: 'abc'.
tag find: [:each | (each missing = 'xyz') or: [each id = 'abc']]

And so far I have simplemented this as:

SoupTag>>find: aBlock
     [(aBlock value: self) ifTrue: [^ self]]
         on: MessageNotUnderstood
         do: [:e | e resume: false].
     children do:
         [:anElement |
         | found |
         found := anElement find: aBlock.
         found ifNotNil: [^ found]].
     ^ nil


I expected this to effectively end up evaluating:

tag find: [:each | false or: [each id = 'abc']]

But all I get is infinite recursion from the doesNotUnderstand. I think
this should work as this little test demonstrates:

[('abc' + 1) + 1]
   on: MessageNotUnderstood
   do: [:e | e resume: 1] " prints 2 "

Any help is greatly appreciated.

Thanks,
Zulq.


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Resume Problems

Stéphane Rollandin
hello,

> SoupTag>>doesNotUnderstand: aMessage
>     (aMessage arguments size = 0)
>         ifFalse: [^ super doesNotUnderstand: aMessage].
>     ^ attributes
>         at: aMessage selector
>         ifAbsent: [super doesNotUnderstand: aMessage]

this can be simpler, since the dictionary lookup will not confuse #id
with #id:, so you can get rid of the arguments size test:

SoupTag>>doesNotUnderstand: aMessage
      ^ attributes
          at: aMessage selector
          ifAbsent: [super doesNotUnderstand: aMessage]

> SoupTag>>find: aBlock
>     [(aBlock value: self) ifTrue: [^ self]]
>         on: MessageNotUnderstood
>         do: [:e | e resume: false].
>     children do:
>         [:anElement |
>         | found |
>         found := anElement find: aBlock.
>         found ifNotNil: [^ found]].
>     ^ nil
>

if there is only one element to be found, the order in which you search
for it does not matter. so you can start by scanning the children, which
makes it possible to write a simple recursive method:

SoupTag>>find: aBlock

      ^ children detect: [:anElement | (anElement find: aBlock) notNil]
        ifNone: [
          [(aBlock value: self) ifTrue: [self]]
          on: MessageNotUnderstood
          do: [nil]].


now I must say your overall design seems to me very complex and really
overusing the DNU mechanism. it should be possible to do what you want
in a much simpler way, but since I don't know what you want to implement
exactly I will not elaborate on this.

regards,


Stef



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Resume Problems

Klaus D. Witzel
In reply to this post by Zulq Alam-2
On Fri, 19 Dec 2008 10:51:01 +0100, Zulq wrote:

> Hi All,
>
> Perhaps I am misunderstanding the behaviour of
>
> I have a class SoupTag which holds a dictionary of attributes and a  
> collection of children which are also soup tags.
>
> As a shorthand for attribute access, SoupTag implements:
...
> But all I get is infinite recursion from the doesNotUnderstand. I think  
> this should work as this little test demonstrates:
>
> [('abc' + 1) + 1]
>    on: MessageNotUnderstood
>    do: [:e | e resume: 1] " prints 2 "

Nah, the result has nothing to do with #on:do: resuming with 1, you better
try

[('abc' + 1) + 1]
    on: MessageNotUnderstood
    do: [:e | e resume: -1]

which still says 2. This because someone, behind you back, put #asNumber
arithmethic into ByteString ... now this attempts (Number readFrom: 'abc')
which gives 0 for your +1 +1 and so 2.

You may want to start DNU testing with ('abc' break; + 1) and then see
where it goes.

HTH.

/Klaus

> Any help is greatly appreciated.
>
> Thanks,
> Zulq.
>


--
"If at first, the idea is not absurd, then there is no hope for it".
Albert Einstein


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Resume Problems

Stéphane Rollandin
In reply to this post by Stéphane Rollandin

> SoupTag>>find: aBlock
>
>      ^ children detect: [:anElement | (anElement find: aBlock) notNil]
>     ifNone: [
>       [(aBlock value: self) ifTrue: [self]]
>              on: MessageNotUnderstood
>               do: [nil]].
>

I just realized this code is wrong, since it can only return a direct
children, not a grandchildren (if your children have children themselves..)

Stef


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Resume Problems

Zulq Alam-2
In reply to this post by Stéphane Rollandin
Hi Stéphane,

Stéphane Rollandin wrote:

> hello,
>
>> SoupTag>>doesNotUnderstand: aMessage
>>     (aMessage arguments size = 0)
>>         ifFalse: [^ super doesNotUnderstand: aMessage].
>>     ^ attributes
>>         at: aMessage selector
>>         ifAbsent: [super doesNotUnderstand: aMessage]
>
> this can be simpler, since the dictionary lookup will not confuse #id
> with #id:, so you can get rid of the arguments size test:

Agreed, thanks.

>
> if there is only one element to be found, the order in which you search
> for it does not matter.

There could be many and order matters. This method is really findFirst,
but I'm trying to keep the names analogous to the library I'm porting.

>
> now I must say your overall design seems to me very complex and really
> overusing the DNU mechanism. it should be possible to do what you want
> in a much simpler way, but since I don't know what you want to implement
> exactly I will not elaborate on this.

The goal is to be able to concisely specify complex find: queries
without having to worry about whether a tag has an attribute. This
shouldn't mean that a tag swallows messages all the time.

A tag may represent a structure like:

<p class="outer">
   <p id="1">ID 1</p>
   <p class="A">CLASS A
     <p blah="blah" id="1">BLAH 1</p>
     <p blah="blah" class="A">BLAH 2</p>
   </p>
</p>

Where each p is a tag, and nested p's are children. To find the BLAH 2:

   blah2 = tag find: [:each | each blah = 'blah' and: [each class = 'A']]

Each tag in the hierarchy before the desired element will throw an MNU
when an attribute is missing. This is desired, i.e.:

   blah2 blah " blah"
   (blah2 attributeAt: 'class') " A "
   blah2 id " should signal an MNU "

Now, maybe catching the MNU is not the right way to do this but I'm not
sure how else to do it while leaving the syntax so concise.

Thanks,
Zulq.


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Resume Problems

Zulq Alam-2
In reply to this post by Klaus D. Witzel
Hi Klaus,

Klaus D. Witzel wrote:

> Nah, the result has nothing to do with #on:do: resuming with 1, you better
> try
>
> [('abc' + 1) + 1]
>    on: MessageNotUnderstood
>    do: [:e | e resume: -1]
>
> which still says 2. This because someone, behind you back, put #asNumber
> arithmethic into ByteString ... now this attempts (Number readFrom: 'abc')
> which gives 0 for your +1 +1 and so 2.
>
> You may want to start DNU testing with ('abc' break; + 1) and then see
> where it goes.

Hmm... I think something is not right or at the very least the semantics
are subtly different than I expect.

VisualWorks:
[Object new blah + 1]
   on: MessageNotUnderstood
   do: [:e | e resume: 1]  " = 2 "

[MessageNotUnderstood signal + 1]
   on: MessageNotUnderstood
   do: [:e | e resume: 1] " = 2 "

Squeak:
[Object new blah + 1]
   on: MessageNotUnderstood
   do: [:e | e resume: 1]  " infinite recursion!!! "

[MessageNotUnderstood signal + 1]
   on: MessageNotUnderstood
   do: [:e | e resume: 1] " = 2 "


If I look at doesNotUnderstand: in both I see that in VW the resumed
value is returned. In Squeak is is not... surely this can't be right?

As for my problem, I think a simpler solution is to pass an
adaptor/proxy object to the block rather than the tag itself. This
adaptor can then marshal behaviour such that it will act as a message
eating null if it receives an MNU from the tag it's looking after.

Thanks,
Zulq.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Resume Problems

Eliot Miranda-2
Hi Zulq,

    I made sure this was fixed in VisualWorks.  Steve Dahl and I fixed this together.  Here's an analogous fix for Squeak.  The essential change is to make Object>>doesNotUnderstand: check if the MessageNotUnderstood exception was handled or not, so 

MessageNotUnderstood new 
message: aMessage;
receiver: self;
signal.
^ aMessage sentTo: self.

is replaced with

(exception := MessageNotUnderstood new)
message: aMessage;
receiver: self.
resumeValue := exception signal.
^exception reachedDefaultHandler
ifTrue: [aMessage sentTo: self]
ifFalse: [resumeValue]

HTH

On Fri, Dec 19, 2008 at 8:13 AM, Zulq Alam <[hidden email]> wrote:
Hi Klaus,


Klaus D. Witzel wrote:
Nah, the result has nothing to do with #on:do: resuming with 1, you better
try

[('abc' + 1) + 1]
  on: MessageNotUnderstood
  do: [:e | e resume: -1]

which still says 2. This because someone, behind you back, put #asNumber
arithmethic into ByteString ... now this attempts (Number readFrom: 'abc')
which gives 0 for your +1 +1 and so 2.

You may want to start DNU testing with ('abc' break; + 1) and then see
where it goes.

Hmm... I think something is not right or at the very least the semantics are subtly different than I expect.

VisualWorks:
[Object new blah + 1]
 on: MessageNotUnderstood
 do: [:e | e resume: 1]  " = 2 "

[MessageNotUnderstood signal + 1]
 on: MessageNotUnderstood
 do: [:e | e resume: 1] " = 2 "

Squeak:
[Object new blah + 1]
 on: MessageNotUnderstood
 do: [:e | e resume: 1]  " infinite recursion!!! "

[MessageNotUnderstood signal + 1]
 on: MessageNotUnderstood
 do: [:e | e resume: 1] " = 2 "


If I look at doesNotUnderstand: in both I see that in VW the resumed value is returned. In Squeak is is not... surely this can't be right?

As for my problem, I think a simpler solution is to pass an adaptor/proxy object to the block rather than the tag itself. This adaptor can then marshal behaviour such that it will act as a message eating null if it receives an MNU from the tag it's looking after.

Thanks,
Zulq.





SqueakMNUaLaVW.1.cs (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Resume Problems

Zulq Alam-2
Hi Eliot,

Eliot Miranda wrote:
> Hi Zulq,
>
>     I made sure this was fixed in VisualWorks.  Steve Dahl and I fixed
> this together.  Here's an analogous fix for Squeak.  

Thanks for the fix.

I've reported the issue in mantis [1], uploaded a unit test and the fix
you attached.

Is it OK to use this fix since it's from a commercial product? Or will
someone need to develop a fix who hasn't seen this or the original code.

- Zulq

[1] http://bugs.squeak.org/view.php?id=7250


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Resume Problems

Eliot Miranda-2


On Mon, Dec 22, 2008 at 8:59 AM, Zulq Alam <[hidden email]> wrote:
Hi Eliot,


Eliot Miranda wrote:
Hi Zulq,

   I made sure this was fixed in VisualWorks.  Steve Dahl and I fixed this together.  Here's an analogous fix for Squeak.  

Thanks for the fix.

I've reported the issue in mantis [1], uploaded a unit test and the fix you attached.

Is it OK to use this fix since it's from a commercial product? Or will someone need to develop a fix who hasn't seen this or the original code.

I wrote the fix I posted in response to your post.  It is not identical to the VW code, but it is essentially the same solution.  The solution is pretty obvious, so I don't think there will be any issues.
 


- Zulq

[1] http://bugs.squeak.org/view.php?id=7250





Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Resume Problems

Ken Causey-3
I highly recommend some summary of this licensing discussion be included
in the bug report.

Ken

On Mon, 2008-12-22 at 11:49 -0800, Eliot Miranda wrote:

>
>
> On Mon, Dec 22, 2008 at 8:59 AM, Zulq Alam <[hidden email]> wrote:
>         Hi Eliot,
>        
>        
>         Eliot Miranda wrote:
>                 Hi Zulq,
>                
>                    I made sure this was fixed in VisualWorks.  Steve
>                 Dahl and I fixed this together.  Here's an analogous
>                 fix for Squeak.  
>        
>        
>         Thanks for the fix.
>        
>         I've reported the issue in mantis [1], uploaded a unit test
>         and the fix you attached.
>        
>         Is it OK to use this fix since it's from a commercial product?
>         Or will someone need to develop a fix who hasn't seen this or
>         the original code.
>
>
> I wrote the fix I posted in response to your post.  It is not
> identical to the VW code, but it is essentially the same solution.
>  The solution is pretty obvious, so I don't think there will be any
> issues.
>  
>        
>        
>         - Zulq
>        
>         [1] http://bugs.squeak.org/view.php?id=7250
>        
>        
>



signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Resume Problems

Zulq Alam-2
OK, done.

Thanks for all the responses, everyone.

Zulq

Ken Causey wrote:

> I highly recommend some summary of this licensing discussion be included
> in the bug report.
>
> Ken
>
> On Mon, 2008-12-22 at 11:49 -0800, Eliot Miranda wrote:
>>
>> On Mon, Dec 22, 2008 at 8:59 AM, Zulq Alam <[hidden email]> wrote:
>>         Hi Eliot,
>>        
>>        
>>         Eliot Miranda wrote:
>>                 Hi Zulq,
>>                
>>                    I made sure this was fixed in VisualWorks.  Steve
>>                 Dahl and I fixed this together.  Here's an analogous
>>                 fix for Squeak.  
>>        
>>        
>>         Thanks for the fix.
>>        
>>         I've reported the issue in mantis [1], uploaded a unit test
>>         and the fix you attached.
>>        
>>         Is it OK to use this fix since it's from a commercial product?
>>         Or will someone need to develop a fix who hasn't seen this or
>>         the original code.
>>
>>
>> I wrote the fix I posted in response to your post.  It is not
>> identical to the VW code, but it is essentially the same solution.
>>  The solution is pretty obvious, so I don't think there will be any
>> issues.
>>  
>>        
>>        
>>         - Zulq
>>        
>>         [1] http://bugs.squeak.org/view.php?id=7250
>>        
>>        
>>
>>
>> ------------------------------------------------------------------------
>>
>>