World: r4wp
[Rebol School] REBOL School
older newer | first last |
MaxV 31-Jul-2012 [693x2] | a: [ 1 2 3 4 5 6] b: copy find/tail a 3 ; you get [4 5 6] c: reverse copy/part a ((index? find a 3 ) - 1) |
and so you get [2 1] | |
Arnold 31-Jul-2012 [695x3] | See, there are other ways. Thanks fo the input all!! |
And now for something completely different. I have a php based form I want to make into a REBOL cgi program. It is to upload some fields into an article-base in my mysql database. Where action is article.php in the php version I changed this to article.r for the REBOL version. I have now the article form shown and when I fill in some fields (but not all) and send the form I get the cgi object ( I use safe-cgi-data-read) but the contents of the formfields is now empty? Any clues what may be the case please? | |
It is POST data. | |
SWhite 31-Jul-2012 [698x2] | I believe that if you do not fill in a field on the form, you do not get an item in the cgi objectl. I seem to recall being confused by that for a while. |
I might have been wrong on the above comment, or it might apply only to checkboxes (that is, if not checked then not present in the object). | |
Maxim 31-Jul-2012 [700x2] | web forms do not send data fields when they are empty or "off", this is true for all types IIRC. |
arnold seems to say that the fields which have data are not sent. | |
Steeve 31-Jul-2012 [702x2] | Arnold, actually you can save one copy and the index? computation. One liner solution: >> c: reverse copy/part a skip b: find/tail a 3 -2 |
Oups no need for the skip -2, so it's even a little faster just using back >> c: reverse copy/part a back b: find/tail a 3 | |
Arnold 31-Jul-2012 [704x3] | Well, I tested again and I was mistaken in thinking php did show the field I previously had filled in when returning after submit and noticing some field was empty. It is the way the browser refills the field when it recognises what you have typed in before.. In the php version all fields of the form are empty as well. So no problem with how REBOL works. (I can display all of the cgi block and everything I typed in is there.) |
The second thing is the validation I have in mind is in fact a client side Javascript/jQuery script before sending the form. | |
Steeve, I like it. Most of the time I prefer readability over speed. This time a little speeding things up comes in handy. | |
Sunanda 31-Jul-2012 [707] | Client-side validation is a nice courtesy touch for the user -- they get told of errors without a network delay. But the server-side code needs to also do full validation as there is no way of guaranteeing the data has been POSTed from your form....Or perhaps the user had Javascript turned off. |
Arnold 31-Jul-2012 [708] | Sunanda, absolutely. I went way too fast on this. Unfortunately there is no way to refill the form fields from the cgi data. Now I say so the DOM and a Javascript maybe able to. I tried some little things but it seems to mess things up more than doing good. |
Sunanda 31-Jul-2012 [709] | If you want the server-sideCGI to send updated values to the client-side JS for that JS to update the web form.....You may need to look at AJAX -- a way for JS to do just that. |
Kaj 31-Jul-2012 [710] | Look at my Try REBOL site for a simple AJAX example |
BrianH 31-Jul-2012 [711x4] | Arnold, what you want to use is FORSKIP. It's like FOR, but with series references instead of numbers. No modifying REVERSE required. |
Here's an interactive example that you can adapt to your script: >> a: [1 2 3 4 5 6 7] == [1 2 3 4 5 6 7] >> i: find a 3 == [3 4 5 6 7] >> b: back i == [2 3 4 5 6 7] >> f: next i == [4 5 6 7] >> forskip b -1 [print first b] 2 1 >> forskip f 1 [print first f] 4 5 6 7 | |
FORSKIP f 1 [...] could be replaced with FORALL f [...] if you like. | |
The only trick is that you either need extra temp vars for the loop variables, or to modify an existing temp var. As a bonus in R3, FORSKIP and FORALL are faster than FOR or FOREACH, since no rebinding of the code block is necessary. | |
Steeve 31-Jul-2012 [715] | Faster than foreach ? I beg to differ good sir, in R2 those are mezzanines and so are slow like hell. I would only use foreach, while and until. But with R3, yeah you're right. |
BrianH 31-Jul-2012 [716x2] | Nonetheless, FORSKIP has less overhead than FOR, even on R2. Simpler mezz code, no BIND/copy overhead. |
You can roll your own code in R2 using WHILE and have it be a little faster, but not necessarily a lot faster. | |
Maxim 31-Jul-2012 [718] | IIRC in all the tests I did, the binding overhead is dwarfed by all other considerations. a single execution of the block is usually longer than the binding process (which is slow, but rebol execution is slower still ;-) . forskip is by far the slowest loop in R2. it was several orders of magnitude slower than foreach. and much slower than an until block ... not worth it.. I'm happy its native in R3. obviously, the time spent within the block with relativise the time spent in the iteration handling. |
BrianH 31-Jul-2012 [719x3] | FOR is slower. You missed comparing FORSKIP to the other mezz loops. FOREACH, UNTIL, WHILE, REPEAT and LOOP are native. |
That's in R2. In R3, FORSKIP is also native, and faster than FOREACH. | |
The only mezz loop in R3 is FIND-ALL. It could be ported to R2 as well, where it would be slightly slower; actually, I was surprised it wasn't there already. | |
Arnold 1-Aug-2012 [722x2] | Okay, thanks FOR this analysis. Concluding, where I am using R2 (because I 'need' VID) I use the foreach forall. The moment R3 is released including VID or replacement I will rewrite this code, promise! |
On the form validation issue. I managed to get things working as I initially intented. Using a Javascript function to change the text of the field: var changer = document.getElementById('fieldid'); changer.value = fieldvalue; Where fieldvalue was filled from the cgi data block cgi/fieldname It was really fun to get this right with all the needed double-quotes and curly braces that alle represent comments in rebol as you know and generate this from within the well-known function emit: func [code] [ repend html code] I had to add an id tag to all the form fields. | |
Steeve 1-Aug-2012 [724] | Arnold, what do you mean by foreach forall ? Arnold, Forall is the worst choice, especially inside another loop. Just look at the code of forall.by yourself. |
Arnold 1-Aug-2012 [725] | Use the foreach before all other options? :) |
Maxim 1-Aug-2012 [726] | in R2... yep :-) |
Arnold 1-Aug-2012 [727x2] | If there is an interest in the basic script with a form with the field testing and refilling of field in the case some errors were found wrt the input. I make a translated anonimised version showing the working. |
Maxim, Steeve, in R2 exactly. The script I need these things for is slowly progressing now. Lots of testing ideas and making decisions for preferred solutions. When it is ready, I will post it on rebol.org | |
BrianH 1-Aug-2012 [729x2] | Foreach doesn't go in reverse, so you're back to modifying your data. If you want to speed up stuff that FORALL does, just look at the source. You can inline the FORALL source, drop the error screening stuff and simplify the code in the WHILE. You will end up with something that can be as fast as the FOREACH, and in some cases faster. |
The "in some cases faster" depends on whether you're going in reverse, and how much data you have. REVERSE can have a lot of overhead if you have a lot of data, so with enough data it would be faster to just work in reverse using a WHILE loop, or possibly better yet a REPEAT with an index that you subtract. | |
Arnold 2-Aug-2012 [731] | Time-out! :D I have enough information to make my script working with reasonable speed. After I publish it on rebol.org we can write out a competition to have it gain speed ;) |
Endo 8-Aug-2012 [732x2] | I wrote a run length encoding function, may be useful for someone else too: rle: func ["Run length encode" b /local v r i j] [ v: 1 r: copy [] j: next i: b unless empty? b [ until [ either all [not tail? j equal? first i first j] [ v: v + 1 j: next j ] [ append r reduce [v first i] v: 1 i: ++ j ] tail? i ] ] r ] |
here is the tests: >> rle "aaabbcx" == [3 #"a" 2 #"b" 1 #"c" 1 #"x"] >> >> rle [] == [] >> >> rle "" == [] >> >> rle [a] == [1 a] >> >> rle [a a a a a] == [5 a] >> rle [a a a a a b b] == [5 a 2 b] | |
DocKimbel 8-Aug-2012 [734] | Endo: I think a much faster version could be coded using PARSE. |
Endo 8-Aug-2012 [735x2] | But don't I need to write two different set of rules for strings and blocks? |
And I'm not that good using PARSE, my PARSE expriments usually stuck with infinite loops :( | |
DocKimbel 8-Aug-2012 [737] | I think it should be doable with one set for both datatypes. |
BrianH 8-Aug-2012 [738x5] | Not quite. You can almost do it in R3, but you need the QUOTE operation for blocks, and QUOTE doesn't work on strings. |
Here's a version for R3 parse, with some optimizations: rle2: funct ["Run length encode" b [series!]] [ output: copy [] x: none r: either any-block? :b [qr: copy [quote 1] [(qr/2: :x) any qr]] [[any x]] parse :b [any [pos1: set x skip r pos2: ( reduce/into [subtract index? :pos2 index? :pos1 :x] tail output )]] output ] | |
The biggest overhead there comes from not preallocating the output block, so there's some reallocation. I don't know how to estimate the size of the output though. | |
You should really have it be case-sensitive though. | |
rle2: funct ["Run length encode" b [series!]] [ output: copy [] x: none r: either any-block? :b [qr: copy [quote 1] [(qr/2: :x) any qr]] [[any x]] parse/case :b [any [pos1: set x skip r pos2: ( reduce/into [subtract index? :pos2 index? :pos1 :x] tail output )]] output ] >> rle2 [a a A b b c d D d d d] == [2 a 1 A 2 b 1 c 1 d 1 D 3 d] | |
older newer | first last |