• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r4wp

[Rebol School] REBOL School

Kaj
30-Jul-2012
[674x3]
Depends on how you intend to use it. If you declare a series without 
COPY or MAKE, it references the data in what you usually think of 
as your source code
This is one of the standard REBOL pitfalls. You can think of such 
data as a constant. If you change it anyway, you're changing the 
representation of your program code
So if you're not going to use the data as constant, use COPY or MAKE. 
For a block with scalar values in it, it doesn't make much difference
Arnold
30-Jul-2012
[677]
I make in init block b: [ 0 0 0 0 ] and use the c: copy b and d: 
copy b as variable block.
Sunanda
30-Jul-2012
[678]
Maxim....Thanks!


I rarely think of using R2-forward to get all those R3 goodies like 
value-of. Makes life much simpler :)


Your only way to fail can be fixed by checking the 'difference of 
the words-of before the main 'all.


Perhaps worth noting for anyone thinking of using the code as written: 
obj2 gets changed in the process.

Thanks again!
Endo
30-Jul-2012
[679x2]
Sunanda: I wrote this function a few months ago for the same task: 
It may not a very good solution but its ok (I think)

similar?: func [
    {Returns true if both object has same words in same types.}
    o [object!] p [object!] /local test
][

    test: [if not equal? type? get in o word type? get in p word [return 
    false]]
    foreach word sort first o test
    foreach word sort first p test
    true
]
It compares words and types, not values.
>> o: context [a: 1 b: "x"]
>> p: context [b: "x" a: 1]
>> s: context [b: "o" a: 1]
>> similar? o p
== true
>> similar? o c
== true
Steeve
30-Jul-2012
[681]
Sunanda,
>> empty? difference third obj1 third obj2
Maxim
30-Jul-2012
[682]
sunanda, actually, I just realized that if I switched the order in 
the all, I can fix the issue :-)

and you are right, I should generate a temp object...  but if you 
put the above in a function it would be like so:

equivalent?: func [ o1  o2 ][

 all [   (words-of   o1) =  (words-of   o2)    o2: make o1 o2     
 (values-of  o1) = ( values-of  (make o1 o2))  ] 	
]
Steeve
30-Jul-2012
[683]
Oups
>> empty? difference/skip third obj1 third obj2 2
Sunanda
30-Jul-2012
[684]
Endo -- thanks....That's a  useful starting point for a function 
that is capable of listing what the differences are.


Steeve -- 'difference on third was my first design ....But it fails 
on (say)
   obj1: make object! [a: 1 b: 2]
   obj2: make object! [a: 2 b: 1]

Maxim .... Nice!
Steeve
30-Jul-2012
[685]
difference/skip doesn't work (I forgot)
Maxim
30-Jul-2012
[686]
note that my function what specifically designed to detect mis-aligned 
words... so this is by design:

>> equivalent? context [a: 1 b: 2] context [b: 2 a: 1 ]
== none
Steeve
30-Jul-2012
[687]
with sort
>> (sort/skip third obj1 2) = sort/skip third obj2 2
Sunanda
30-Jul-2012
[688]
That looks good. Steeve -- thanks!
Arnold
30-Jul-2012
[689]
Hi looking for a better REBOL way to do the next thing: a: [ 1 2 
3 4 5 6 ] I have 1 of the values in this series and  want to do a 
foreach/forall on the series left of this value from right to left 
and also a foreach on the series on the right of this value but now 
from left to right. So say I chose 3 for the value then I need [ 
2 1 ] and [ 4 5 6 7 ]. This is my solution b: reverse copy/part a 
find a 3 and c: reverse copy/part a find reverse a 3 but now >> a
== [6 5 4 3 2 1]

And I don't want that and I don't like undoing the reverse each time. 
Do I need a temp for reverse a because c: reverse copy/part a find/last 
reverse copy a 3
** Script Error: Invalid /part count: 3 2 1
?
Sunanda
30-Jul-2012
[690]
You could use FOR to count yourself down:
     blk: [1 2 3 4 5 6]
     val: 3
     for nn val - 1 1 -1 [print blk/:nn]
       2
       1
Arnold
30-Jul-2012
[691]
Thanks Sunanda for this option. One extra tricky thing is the length 
of the series varies and I feel I am doing to much bookkeeping myself 
already.
Maxim
30-Jul-2012
[692]
yes, Arnold, be very careful with reverse... if you are part/way 
it will only reverse part of the series.
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.