|
nk4um Moderator
Posts: 485
|
2010-05-20T11:07:30.000ZMay 20, 2010 11:07Fixed
Ok, I''ve got a solution. It was an interesting corner case, one that the implementation didn''t consider. Now arguments can
only be resolved in the script that they were passed too. We''ll post a fix for this on the repository tomorrow.
Thank you for finding this and your patience for a fix.
Cheers, Tony
|
|
nk4um Moderator
Posts: 485
|
2010-05-19T21:22:01.000ZMay 19, 2010 21:22
Yes, sorry for not being clear. I''ll get back to you soon. I''m tending to think that we need to limit the scope of resolution
for the arguments. Reading up about clojures: http://en.wikipedia.org/wiki/Closure_%28computer_science%29I think that scope for the arguments should be limited to the lexical scope, i.e. within the same script. Tony
|
|
nk4um User
Posts: 111
|
2010-05-19T21:14:19.000ZMay 19, 2010 21:14
|
Let me think about them and get back to you.
|
Oh, you mean none of these solutions are possible right now? Sorry about the previous message then! I felt like a newbie in
need of more explanations... :) Gregoire
|
|
nk4um User
Posts: 111
|
2010-05-19T15:48:29.000ZMay 19, 2010 15:48
Hi Tony!
|
1) set a <null> value for the argument and test for that rather than existence
|
Yes it would solve the problem. But how do you define a default value for the arguments, in "module.xml"? And on the DPML
side, how do you test for a given value? Thank you, Gregoire
|
|
nk4um Moderator
Posts: 485
|
2010-05-19T14:25:09.000ZMay 19, 2010 14:25
Thank you for the visualizer trace. I understand that you are recursively calling the DPML script from inside xquery. The
problem is as I suspected: that the arguments passed to the outer DPML are being resolved inside the inner. This is because
they are being aliased with same underlying identifier and so both inner and outer are looking for the same resource and it
is in scope from the inner script too.
This situation was anticipated but not considered a problem - until now. We thought that it was useful to have these outer
"variables" available. But the problem is there is no way to hide them. There are a number of solutions to this. These include:
1) set a <null> value for the argument and test for that rather than existence 2) change the resolution for arguments in DPML to that they can only be resolved inside the script in which they were defined.
Let me think about them and get back to you.
Cheers, Tony
|
|
nk4um Moderator
Posts: 485
|
2010-05-18T20:32:23.000ZMay 18, 2010 20:32
Hi gregoire, I think I see what you are doing but I''m not quite following how the recursion is happening. Can you email me a visualizer trace (tab at 1060research.com) and I''ll take a look and get back
to you. DPML does use more a closure style approach rather than functions, i.e. whatever is in the scope can be found including arguments but
it looks like you are leaving DPML and going into XQuery?
Send me the visualiser trace and I should understand then.
Cheers, Tony
|
|
nk4um User
Posts: 111
|
Hi, I''ve set up a webservice with all the towns of France, which can be used to display all towns whose names begin with a given
set of letters. To benefit from NetKernel''s ability to cache resources, I made this webservice recursive. So when you call it with the letters
"Carca", it calls itself with the parameter "Carc", and so on, until the parameter is only 3 characters long ("Car"). Then
the webservice reads the data and returns the list. The idea is that if the user is typing a town name, it will first type
"Car", then "Carc", then "Carca", and the new result is always a subset of the previous one. So using recursivity ensures
that the more characters are typed, the fastest the result is displayed. This initial version of the algorithm works very good.However with the letters "Saint", the magic stops because there are around 3000 towns and villages whose names begin like this. That''s
too much data for a simple autocompletion mechanism. So my idea is to keep the original recursive webservice, but to send
its output to a simple XSLT script which would strip everything but a given number of towns. In order to do this, I modified my module.xml so that I could use two optional arguments "indiceMin" and "indiceMax". The initial call would be:
res:/services/towns/Marsei/1-10
|
Then all the recursive calls would not use the optional /1-10 parameter. They would be:
res:/services/towns/Marse
|
then then So the algorithm should be very simple:
if (the "1-10" parameter exists) then (call WS) (cut the returned list) else (call WS)
|
I wrote this DPML script to do this job:
<sequence> <if assignment="response"> <cond> <request> <identifier>arg:indiceMin</identifier> <verb>EXISTS</verb> </request> </cond> <then> <sequence> <request assignment="towns"> <identifier>active:xquery</identifier> <argument name="operator">res:/resources/scripts/towns.xql</argument> <argument name="lieu">arg:townName</argument> </request> <request assignment="response"> <identifier>active:xslt</identifier> <argument name="operator">res:/resources/scripts/cut.xsl</argument> <argument name="operand">this:towns</argument> <argument name="indiceMin">arg:indiceMin</argument> <argument name="indiceMax">arg:indiceMax</argument> </request> </sequence> </then> <else> <request> <identifier>active:xquery</identifier> <argument name="operator">res:/resources/scripts/towns.xql</argument> <argument name="townName">arg:townName</argument> </request> </else> </if> </sequence>
|
As you can see, the decision to call the "cut.xsl" script is based upon the existence of the "arg:indiceMin" parameter. The problem is : the recursive calls (which don''t use the optional parameter "/<indiceMin>-<indiceMax>"), still sees the "arg:indiceMin"
defined by the first call (the one with the parameter "/1-10"). So the returned list is truncated after each recursion. This
is obviously very wrong and completely breaks the recursive algorithm. The question is: is it possible to say that the "arg:indiceMin" argument should be "local" (viewable only by the current call) and not "global"
(viewable by all the subsequent calls)? So that only the initial call comes in the "then" block and all the recursive calls
go through the "else". Thanks for your help, Gregoire [/xml]
|