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. |
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 |
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 |
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 |
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. |
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. |
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, SqueakMNUaLaVW.1.cs (2K) Download Attachment |
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 |
On Mon, Dec 22, 2008 at 8:59 AM, Zulq Alam <[hidden email]> wrote: Hi Eliot, 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.
|
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 |
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 >> >> >> >> >> ------------------------------------------------------------------------ >> >> |
Free forum by Nabble | Edit this page |