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

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp5907
r3wp58701
total:64608

results window for this page: [start: 32901 end: 33000]

world-name: r3wp

Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public]
Henrik:
24-May-2009
Something more basic, that you may have skipped or forgotten: Contexts 
are just objects. They are just a clumped together set of words with 
values.

The big secret is revealed here:

>> source context
context: func [
    "Defines a unique (underived) object."
    blk [block!] "Object variables and values."
][
    make object! blk
]


So when you make a new object, you make a new context. The definition 
block (shown as blk in the source for context) is then bound to this 
new context. You can run ordinary REBOL code inside the object definition 
block. You are not restricted to the obvious syntax of set-word! 
and value pairs:

d: make object! [
	b: "hello"
	reverse b
]
d/b
== "olleh"


Of course after the definition block has been parsed to become an 
object, only the key/value pairs remain.

Remember that and you can get very far with contexts.
mhinson:
24-May-2009
I think I have understood what it is that has been preventing me 
from understanding BIND.

I was expecting BIND to make a persistant difference to the contexts, 
but now I have realised that is not the case, it only acts as a function 
to return information when it is called.  That was a tough one to 
fight through.   However, now I understand Henrik's example, but 
the example in the manual still confuses me.  
words: [a b c]

    fun: func [a b c][print bind words 'a]  ;; why is this not  ... print 
    bind words 'a 'b 'c]

Does this mean that bind causes fun to be joined to the context of 
words, for all the variables used in the words context? 

I think I am also still confused about which direction the context 
moves.  Sorry to be asking again, but I do want to understand this 
completely. In Henrik's example it seems to be "do b in the context 
of c" but in the manual example it seems more like "print words (which 
in the global context ) as if the context variables of words had 
been assigned the values of the current context....  I am off to 
bed now to sleep on it.   Thanks.
mhinson:
25-May-2009
I see the bind function can do both the things I noticed above.  
I have stalled with reading Ladislav's Bindology paper at section 

9.1 I dont understand what a-word has become, and why.  I dont understand 
how 'a might be referenced in   bind 'a a-word   as it has no mention 
in the example, so I dont understand what is being demonstrated.
Steeve:
25-May-2009
words: [a b c]					;**  words, a, b, and c belong to the global context.

fun: func [a b c][print bind words 'a]		;** 'it is asked to change 
the context of the words comprise in the block "words".

      ;** After that, they are not belonging to the global context anymore, 
      but to the context of the function.
mhinson:
25-May-2009
Thanks Steeve, I think bind is becoming a bit clearer to me. Your 
comments seem to make sense to me now.
BrianH:
25-May-2009
Words are immediate values, so BIND returns a new value when passed 
a word. BIND changes blocks passed to it, but BIND/copy changes a 
deep copy. The words in blocks are replaced with new words that have 
the same symbol but a different binding.
Steeve:
27-May-2009
missing a reduce, pal
Henrik:
28-May-2009
the alternative is compose which offers a /deep refinement:

creature: compose/deep [(to-word animal) [(named) [(breed)]]]


and all parts you wish to compose in the block must be wrapped in 
()'s.
mhinson:
28-May-2009
That is very cool...  And I feel happy that I predicted there might 
be a thing that did that too... it is much more elegant than lots 
of reduce statements everywhere.  Thanks.
Graham:
28-May-2009
Compose wasn't there in the beginning ... it was a later add on because 
of these issues
mhinson:
29-May-2009
Hi, I have been trying for the last hour or two to get this code 
to behave in the way I want. 
data: {
thing toy
 owner child
thing house
 owner adult
}

thing: copy []
owner: copy []
StructuredData: copy []

parse/all data [ 
	any [

  ["thing " copy thing to newline (append StructuredData reduce[to-word 
  thing[]])]

  |[" owner " copy owner to newline (append StructuredData/(to-word 
  thing) compose/deep [owner[(owner)]])]
		| skip
	]
]
probe StructuredData

[toy [owner ["child"] owner ["adult"]] house [owner ["child"] owner 
["adult"]]]


My problem is that the toy & the house are owned by the child & the 
adult. It seems the things are linked to each other in a way I dont 
follow.  If I assign the values directly, rather than using the parse, 
then the StructuredData contains what I expect.
[toy [owner ["child"]] house [ owner ["adult"]]]
Chris:
29-May-2009
Your problem is this line:


 ["thing " copy thing to newline (append StructuredData reduce [to-word 
 thing []])]

Specifically this part:

	reduce [to-word thing []]


The last block here is never copied.  When you append your data with 
the reduced block, the owners block is always the same (as in 'same?) 
block.  You need to create a new block each time:

	reduce [to-word thing copy []]
or
	reduce [to-word thing make block! 5] ; 5 is arbitrary
mhinson:
30-May-2009
Thanks Chris.  There are several things I have learnt from this: 
 COPY has more varied use than I was aware of. In this case I think 
COPY is making sure I am adding a unique empty block, rather than 
a link to this one.


I still cant quite get my head round an empty block being something 
that can be referenced again later, although I know I have read about 
it previously & know it is important.

Why do I not seem to need COPY in my following example?
StructuredData: copy []
thing: copy "toy"
append StructuredData reduce[to-word thing[]]
owner: copy "child"

append StructuredData/(to-word thing) compose/deep [owner[(owner)]]

thing: copy "house"
append StructuredData reduce[to-word thing[]]
owner: copy "adult"

append StructuredData/(to-word thing) compose/deep [owner[(owner)]]

probe StructuredData
[toy [owner ["child"]] house [owner ["adult"]]]
Chris:
30-May-2009
mh: In the case above, when you were using 'reduce, you were evaluating 
the first block, in which the second block is just a value.  When 
you evaluate a block value, it is not in turn evaluated:

	>> [i'm not code]
	== [i'm not code]

It's important to remember when you do some deeper evaluation:

	>> code: [[]]  ; block containing a block value
	== [[]]
	>> append code/1 'a  ; modify block value
	== [a]

 >> result: do code  ; evaluate block, block value returned - now 
 referenced by 'result
	== [a]
	>> append code/1 'b  ; modify block value
	== [a b]
	>> result  ; result is referencing the same value
	== [a b]
	>> append result 'c
	== [a b c]
	>> code
	== [[a b c]]


Every value in REBOL is merely referenced to by the language.  Sometimes 
explicitly:

	result: []
	probe result

Or not:

	code: [[]]
	probe code/1

Or both:

	code: [[]]
	result: code/1
	probe same? code/1 result
mhinson:
30-May-2009
Thanks Chris, Graham, Izkata   I feel like I half get this, but not 
well enough to be confident yet. I have been trying to create a really 
simple example where two parts of the same block are really the same 
items, so changing either, changes both because I think it will help 
me understand better & that was the behaviour in my original example. 
 Perhaps if I study this for another couple of hours I will get a 
breakthrough with it.  Thanks.
Chris:
30-May-2009
Such as?:

	>> attr: []
	== []
	>> cont: reduce [attr attr]
	== [[] []]
	>> insert attr 'c
	== []
	>> insert first cont 'b
	== [c]
	>> insert second cont 'a
	== [b c]
	>> cont
	== [[a b c] [a b c]]
Izkata:
30-May-2009
Try this:  Predict the output of these function calls:
foo: func [/local A B][
   A: []
   B: copy []
   print mold append A {a}
   print mold append B {b}
]
foo
foo
foo
mhinson:
31-May-2009
;Thanks Izkata, I predicted the outcome correctly. I went on to try 
this:
D: [{bar}]                                        ;; global D
foo1: func [D][D: [] print mold append D {d}]     ;; 
foo2: func [D][D: [] print mold append D {d}]     ;; 
foo1 D  ;; value of global D passed to function (but not used)

foo1 D  ;; function references its own local value of [] to which 
it keep appending {d}
foo2 D  ;; same as foo1 but references its own [] ?pointer? thing
D       ;; still references un changed global D

foo1: func [D][D: [] print mold append D {d}]   ;; rewriting foo1 

foo1 D                                          ;; new foo1 function 
has new [] pointer

foo3: func [][D: [] print mold append D {d}]    ;; D is not passed 
to the function

Foo3          ;; now we are changing global D and making it reference 
foo3 [] pointer 
D             ;; proof global D has changed

;; I think the bit that was making it hard for me to understand was 
that 

;; referencing the same empty block in a function means the actual 
exact function, 

;; a second copy of it even with the same name, sets up a new local 
pointer. And also the unexpected localness confused me.


;; Question, do my comments show that my understanding is now correct 
please?
mhinson:
31-May-2009
What is the length limit for a comment line please?  some of my comment 
lines are being intrepreted.  I think it is the length of them.
mhinson:
31-May-2009
no, just ;; in front of a few very long lines.
mhinson:
31-May-2009
it is like that because I have a bunch of lines that will become 
a function & I am comparing them in some cases, and excludeing them 
in other cases to debug my code.
Graham:
31-May-2009
and you only need a single ;
mhinson:
31-May-2009
Those lines I posted still do strange stuff with a single ;  at the 
beginning.  Could it be a bug with the console?  I do 2 ;; to make 
them stand out more, although syntax highliting does that already. 
Thanks.
Sunanda:
1-Jun-2009
A tip I picked up off of the Mailing List years ago (thanks to whoever 
it was)
   doc: does [do clipboard]
then you need to just type
  doc
to
  DO Clipboard://
mhinson:
3-Jun-2009
Hi, is thre a neater way to do this please an avoid so many reduce 
statements please?
QQ: []

func1: func [o1] [append QQ copy/deep reduce [reduce o1 reduce reduce 
[reduce o1]]]
owner: "Luke" 
func1 'owner
[owner ["Luke"]]
Sunanda:
4-Jun-2009
Multiple copies of REBOL is a pain that several of us have.
Graham:
4-Jun-2009
It's a result of programming with Rebol which tells us to use 'copy 
to be safe
mhinson:
4-Jun-2009
With the shortcut  to do clipboard://  it complains if there is no 
 rebol[]   header.  Do folk only use it for bigger blocks of code, 
rather than a few lines that need testing?  As I suppose pasting 
it straight into the console for small chunks works pretty well? 
Thanks.
mhinson:
5-Jun-2009
Hi, I have associated .r files with Rebol/view, but when I open my 
.r files I get an error
** Access Error: Cabbot open /c/documents
** Near: do/args script system/script/args


I tried associating .rs with Rebol/View & that works ok...  I suspect 
this is a windowsy problem, any suggestions please?
Maxim:
5-Jun-2009
XP was designed for dumb users... vista went a step further and added 
that pre-requisite to its analysts.
BrianH:
5-Jun-2009
Software at its best is a distillation of your smarter moments, for 
later use during your dumber ones :)
mhinson:
8-Jun-2009
Hi, I seem to be answering more of my own questions for the last 
few days which is encouraging, but I am wondering if I am getting 
into bad habits as I have no solid programming background & apart 
from the tips I have got here I am just self-taught.  

Is there anywhere I can put a few hundred lines of code to be torn 
to shredds please?  I don't paticularly relish the idea, but I suspect 
it will be a good learning experience.
Sunanda:
8-Jun-2009
Few hundred lines of code!? Congratulations on writing them.....But 
can you extract a subset (say a function of two that you are especially 
proud of) for analysis. 100s of lines of code is going to be hard 
for anyone to wrap their mind around for comment.

Having said that, possible locations: Here or the mailing list.
You tend to get more thought out replies on the ML.
You get  more instant interaction here.
Sunanda:
8-Jun-2009
You could also try reboltalk -- though that seems overrun with spam 
a lot these days:
http://www.reboltalk.com/
mhinson:
8-Jun-2009
It is mostly a parse with about 8 small functions that are called 
within the parse to identify special cases, expand ranges & mess 
about with IP address info.
mhinson:
8-Jun-2009
I think the fact that I can readily extract a decent function to 
post means that I have been using too many globals & getting my code 
a bit muddled.  Thanks for the feedback, I will post something once 
I get it a bit more untangled....  It just went like that, honest 
I didnt write it like that to start with.. :-(
mhinson:
8-Jun-2009
I am intrested in Cisco networking & writing tools related to that 
area of technology, not sure that is a very prominent interest in 
the AltME world??
mhinson:
8-Jun-2009
This is a unique place.  It is a priveledge to be invited here.
Sunanda:
9-Jun-2009
The Library does sometimes have trouble with scripts.

It needs to load the script to get header information. But the Library 
is running on an older version of R2. Some newer scripts cannot be 
loaded as they contain syntax elements that crash the version the 
Library is running.
We have some creative work-arounds.

Mike can you email me your script (right click my name for email 
address). I'll see what the options are.
Thanks.....You are a natural at finding bugs!
mhinson:
9-Jun-2009
Hi, I have sent the whole thing to Sunanda as the script is ok in 
the browser, but has a few (other) problems being loaded into the 
Library. Probably down to me doing strange noobie things. In the 
case above the library prefers ... intIpaddrS/:count1 ...   Which 
seems better in any case so I have changed it.
Sunanda:
9-Jun-2009
Thanks Mike.

It's [old REBOL version + REBOL not being backward compatible].


There is a theory that REBOL does not need to be backward compatible, 
as old applications can continue to run on older versions of the 
interpreter. That theory is fine in many cases.....


.....But it fails in the case of REBOL.org -- we're an old (verging 
on legacy) application that consumes REBOL code as data ..... We 
fail in some cases because the code we try to consume as data crashes 
the version of the interpreter we use.


I have an idea for (yet another) creative work around for the issue 
Mike has.....But I also have to spend a few days away from REBOL 
coding, so no immediate solution forthcoming. Sorry!
mhinson:
10-Jun-2009
Hi, is there any clever Rebol way to access the Tuples in this block 
by the associated numbers 80 & 4 please?
b: [80["8.8.8.8" "random"] 4["4.4.4.4"]]


if they were words it would be easy, but with numbers I am wondering 
if I just have to search for them & find the index & add one? Or 
perhaps convert the numbers into words by prepending them with a 
letter perhaps? Thanks.
mhinson:
10-Jun-2009
This solution seems a bit messy, so I wondered if there was a neater 
way.
>> b: [_80["8.8.8.8" "random"] _4["4.4.4.4"]]
== [_80 ["8.8.8.8" "random"] _4 ["4.4.4.4"]]
>> b/_80
== ["8.8.8.8" "random"]
mhinson:
10-Jun-2009
That is perfect....  Again I learn a new word for my Rebol conversations. 
 Thanks Sunanda
mhinson:
13-Jun-2009
Hi, I have written this function and would be glad of any comments 
please.  I know it is only simple stuff but I want to try any learn 
to write code well, not just hack stuff together that just about 
works.  Thanks. 
;; Generate all IPv4 dotted decimal masks
AllMasks: has [a b c d allMasks][
	allMasks: []
	if (allMasks = []) [
		for count 0 7 1 [ 
			i: to-integer power 2 (count)	
			a: 255.255.255.255 - to-tuple rejoin ["0.0.0." (i - 1) ""]
			b: 255.255.255.255 - to-tuple rejoin ["0.0." (i - 1) ".255"]
			c: 255.255.255.255 - to-tuple rejoin ["0." (i - 1) ".255.255"]

   d: 255.255.255.255 - to-tuple rejoin ["" (i - 1) ".255.255.255"]
			insert allMasks  reduce [a b c d]
		] 
		sort/all/reverse allMasks
		insert tail allMasks 0.0.0.0
		print "Created all IPv4 masks"  ;; debug
	] return allMasks
]
Sunanda:
13-Jun-2009
Any code that works is fine by me.....!

You could make your to-tuples a little tidier by utilising the fact 
the to-tuple will take a block of integers, eg:
    to-tuple [255 255 255 248]
    == 255.255.255.248
Paul:
13-Jun-2009
Hi mhinson, a couple things at first glance.  Beware setting a word 
to series data.  One of the big pitfalls newcomers have is that if 
they intend to reuse a function that contains a series being set 
that it can result in the series getting recursively populated.  
To avoid that we often use the 'copy word when setting series.  Although, 
by design sometimes we want the previous behavior.  The other thing 
is to get rid of the return at the end.  Just end your statement 
with allmasks.  You should really only need the 'return if you intend 
to pre-empt the full execution of the body block of the function.
Sunanda:
13-Jun-2009
Use of 'return is partially a personal style issue. It is, literally, 
not needed if the last value your function handles is the one you 
want returned; in that case omiting the 'return can speed up a function 
considerably.


On the other hand, consider "literate programming" conventions: it 
can be polite to spell out the details so future code readers do 
not need to recapitulate your clevernesses just to work out what 
is returned......The code snippet below can return three separate 
things: spelling it out would help future generations!

    f: func [a b][
      either a > b [
          print a
         ][
         if a = b [b + 5]
        ]
     ]
mhinson:
13-Jun-2009
Hi guys, thanks for the tips, it is looking neater allready.

About setting the words to series data, is this us in my gode a bad 
example would you say?  I intended that the function would only ever 
need to calculate the values once, but perhaps my method is not secure?

Thanks for the tip about series pickers, that way looks a bit reversed 
so I would have probably got it wrong.
Sunanda:
13-Jun-2009
Another thought -- you may be able to avoid the block and to-tuple 
stuff by modifying a tuple:
    t: 255.255.255.255
    == 255.255.255.255
    t: poke t 4 t/4 - 1
    == 255.255.255.254
Izkata:
13-Jun-2009
I wouldn't call it a bad example of storing series data, exactly, 
just unusual.  Look at this:
>> foo: func [/local bar][
[    bar: []
[    if empty? bar [
[        print {Generating..}
[        insert bar 1
[        ]
[    return bar
[    ]
>> foo
Generating..
== [1]
>> foo
== [1]

If the function needs to be called multiple times, the data is stored 
and doesn't need to be re-created each call, getting a pretty good 
speedup.  This is what foo now looks like:
>> source foo
foo: func [/local bar][
    bar: [1] 
    if empty? bar [
        print "Generating.." 
        insert bar 1
    ] 
    return bar
]
mhinson:
14-Jun-2009
I am wondering if there is a better or simpler way to get the index 
when using FIND? and the value is not found, my attempt seems more 
complex that I would have expected from Rebol, so I suspect there 
is a method or function I have not yet discovered.  :-)   Thanks.
a: find {abd} "e"
either none? a [i: 0][i: index? a]
Henrik:
14-Jun-2009
The second line can be:

any [all [a index? a] 0]
Henrik:
14-Jun-2009
if you want to keep the 'either, it internally tests for none, so 
you could shorten it to:

i: either a [index? a][0]


You can see what kind of tests it makes by using TO-LOGIC on a value 
you want to test.
Paul:
14-Jun-2009
Because the argument to index? is supposed to be a series and 'none 
is not a series.
mhinson:
14-Jun-2009
Then should FIND return an empty series if the target is not found? 
rather than none?  I thought none was a special case & might be handled 
differently by some functions that expect specific types.
Paul:
14-Jun-2009
But see Find returns none BASED on a series argument.  You were suppling 
'none as the argument.
Henrik:
14-Jun-2009
One can say that FIND limits its input to series! to eliminate errors 
as early as possible. Imagine if FIND accepted NONE and we had some 
intricate series of FINDs on a single block 'a:

find find find/reverse find a 'e string! 'f integer!
== none


If 'a is a dynamic block (not known when you write the code) where 
is the error?


It's not a great example, but it raises the question of how forgiving 
you want your functions to be, when you write them. I consider that 
you generally want to catch errors as early as possible, to avoid 
having to write "forgiving" code that can take up space and complicate 
things and worst of all, make the code much harder to debug. But 
it's only one school of thought.
mhinson:
14-Jun-2009
ANY & ALL are quite hard, but I think I am getting it..  This confused 
me for a while, but now I understand.
a: b: c: d: []

any [ do[a: 1 false] do[ all[ do[b: 2 false] do[c: 3 true]] true] 
do[ d: 4 true]]
print rejoin["a,b,c,d=" a "," b "," c "," d]
This is what I think is happening.  

a is set but as the block returns false the ANY block evaluation 
continues

b is set within the nested ALL block & as it returns false the ALL 
block evaluation stops

the do which contains the ALL block returns true so the ANY block 
evaluation stops
Izkata:
14-Jun-2009
Yes; ANY is a shortcut for OR'ing vaues together, and ALL is a shortcut 
for AND.
Henrik:
14-Jun-2009
I use ANY and ALL a lot because they can be handy in situations where 
an EITHER can be too cumbersome, such as inline result output for 
printing:

print any [select names name "No Name Found"]

In other cases they take up more space than an EITHER.
Tomc:
14-Jun-2009
unlike a series of and/or  any/all will stop evaulating conditions 
at the first condition that deternims the result
Gregg:
14-Jun-2009
I take that back, I've messed up a couple times and created uncontrolled 
growth in the memoized data. You do have to watch out for that. :-)
Oldes:
15-Jun-2009
instead of:
any [ do[a: 1 false] ]
why not to use just:
any [ (a: 1 false) ]
mhinson:
15-Jun-2009
That is interesting Oldes.  I thought I tried something like that, 
but now I see I must have been confused about what the () do.

so does the ANY cause the () to evaluate its contents?  If I just 
put [(true)] it is not evaluated, but all[(true)] is.   Then again 
to-logic [(false)] is not evaluated. There must be a trick I am missing 
here I think.  Thanks,
Gregg:
15-Jun-2009
Using blocks and *not* evaluating their contents--perhaps "deferring 
evalutation" is a better way to say it--is also a powerful aspect 
of REBOL. Being able to prevent parens from being evaluated is a 
good example.
mhinson:
15-Jun-2009
I think I would love to know when evaluation occurs.. So far I mostly 
just have to test every fragment of code I write & if I am lucky 
I guess right first time. I am slowly getting better at it, but I 
would say it is often a bit of a mystery.
mhinson:
15-Jun-2009
I have submitted a script to the Library.  http://www.rebol.org/view-script.r?script=cisco-extract.r

Its purpose (apart from learning Rebol) is to read Cisco config files 
& present the interface information in a tab separated text file.
mhinson:
17-Jun-2009
Hi, I have done a bit with fairly basic parse expressions, but I 
am now trying to understand more.

Am I right to think that ALL SOME & ANY are the only controls of 
this type?  Or am I missing another in the set?

Do ALL & ANY work in the parse dialect the same way that they do 
described above?  Thanks.
mhinson:
17-Jun-2009
ok.  I really like the ? help functions. While learning they help 
a great deal.  Thanks.
BrianH:
17-Jun-2009
Unfortunately, parsing is considered a hard subject. Learning PARSE 
might take some time if you haven't had experience or taken a class 
in parsing before, even when you read the online docs.
mhinson:
17-Jun-2009
I had a really usefull walk-through of Parse with Maxim a few weeks 
ago here.  I wouldn't say Parse has been any harder for me to learn 
about than any other aspect I have delved into so far, in fact I 
found the GUI stuff the most confusing to get ahead with.
mhinson:
17-Jun-2009
I started looking at the R3 Gui too.  I am mostly intrested in drawing 
my own graphics on screen, controled by a bit of maths & trig, but 
with real-time interaction from sliders etc.  I suspect this is not 
the sort of thing that newbies are expected to do, but writing text 
in different fonts on coloured buttons dosn't do anything for me.. 

I am finding that using any part of Rebol makes it easier to understand 
the discussion here & get more in tune with what behaviour to expect.
mhinson:
17-Jun-2009
I have been working on my Parse understanding and came up with this:
parse/all {aX--baX~~a--aX~~} [some
  [
    "a" h: some[ 
      [ 
        ["--" :h copy result to "--" (print result) thru "a" h:]
        |["~~" :h copy result to "~~" (print result) thru "a" h:]
      ] |[skip]
    ]
  ]
]
I am extracting the text between "a" and either "--" or "~~" 

Is my method a reasonable aproach or is there a simpler or more readable 
way to do this sort of thing please?
Ladislav:
17-Jun-2009
here is my way:
parse/all {aX--baX~~a--aX~~} [
	"a"
	some [
	    s:
		any [
		    t: ["--" | "~~"] (result: copy/part s t print result) break
			| skip
		]
		thru "a"
	]
	to end
]
Izkata:
17-Jun-2009
If the empty one doesn't need to be recorded as empty:
parse/all {aX--baX~~a--aX~~} [                             
   some [

      ["a" some ["--" break | "~~" break | X: (print X/1) skip] | skip]
   ]
]
Izkata:
17-Jun-2009
Mine'll also only grab one character at a time, so {abbb--} would 
need something extra
Graham:
18-Jun-2009
If it's a fixed length format .. why bother use parse and just use 
copy/part ?
mhinson:
18-Jun-2009
Thanks for the examples, I will be digesting them for a while I think.

I started looking at a real life problem where the ending sequence 
of what I wanted to extract was two different things (". " OR "." 
newline), that led me to look at this sort of structure & try to 
understand how parse rules can be adapted.  My example is educational 
only, not from real life. It was intended to be a short example of 
non-fixed length format with multiple cases to extract and 2 different 
end-of-data-to-extract markers. I think a better example of what 
I intended should have XX as the data to extract in one case. {aX--baX~~a--aX~~aXX~~} 
perhaps.   Thanks.
Izkata:
18-Jun-2009
Righto, here's my updated one - good practice for me, too, I rarely 
use parse like this:

parse/all {aX--baX~~a--aX~~aXX~~} [                              
          

   some [                                                           
             

      ["a" S: some [E: ["--" | "~~"] (print copy/part S E) break | skip] 
      | skip] 
   ]
]
Steeve:
18-Jun-2009
Lot of ways with parse...

content: complement charset "-~"
parse/all {aX--baX~~a--aX~~aXX~~} [

   some [                                                           
             

      thru #"a" opt [copy result some content ["--" | "~~"] (print result)]
   ]
]
mhinson:
19-Jun-2009
It is strange this parse learning..  I look at these rules & understand 
what is happening.  BUT I try to write my own without looking at 
these & I always get confused again.  It dosn't seem very complex, 
but it does seem very easy to get wrong. Does any one have any tricks 
for formatting the code in a way that helps keep track of what the 
logic is doing?
mhinson:
20-Jun-2009
I remeber looking at this before, but I couldn't work out how to 
use it... With a bit of luck I will understand it now, although it 
does look quite complex. Thanks.
mhinson:
20-Jun-2009
Looks like the instructions are written for someone who already knows 
how to use it...
- run the script  ## this dosn't seem to do anything

- Run the parse-analysis.r script and use the tokenise-parse function 
to get the base data.  ## dont understand what this means, tried 
a few things but they all give errors.

The example works, but I cant even see the parse expressions in it 
so I dont understand why it works or how to adapt it for my own example.

When I first looked at this in April I got quite frustrated because 
it looked as if it was there to help newbies learn about parse, but 
it was too hard for newbies to understand how to use... now I can 
at least understand how to run the example.  Thanks
Sunanda:
20-Jun-2009
I sympathise....the documented examples for parse-analysis are certainly 
less than clear on what steps you need to take to prep a parse for 
analysis.


If you have worked it out for some simple examples, then adding a 
discussion thread to the script may help other's in future.
Gregg:
21-Jun-2009
I often have trouble visualizing how things work, and I don't feel 
that I really understand something until I can do that.  With PARSE, 
even though it can be tedious and create volumes of output, it may 
help to write some simple grammars and have it print output for every 
rule. Have a probe at the start of the rule, and a probe if it's 
successful, nesting the output helps a lot too.


Don't get discouraged, it's not an easy thing to grok for a lot of 
people.
Gregg:
21-Jun-2009
In my largest grammar, where incoming data may be malformed, I've 
found it invaluable to have the rule tracing built in, enabled by 
a flag. e.g. 

    TSAFE-CHAR: [
        (rule-trace "TSAFE-CHAR IN")
        copy =TSAFE-CHAR charset-21
        | charset-22
        | charset-23
        | charset-24
        | charset-25
        | NON-US-ASCII
        (rule-trace "TSAFE-CHAR OUT")
    ]

    rule-trace: func [value /local rule-name action] [
        rule-name: first parse value none

        ;print [tab rule-name tab found? find don't-trace rule-name]
        action: second parse value none
        if all [
            any [
                trace-rules? = true
                action = form trace-rules?
            ]
            not found? find don't-trace rule-name
        ][
            val: attempt [mold get to word! join "=" rule-name]
            print ["===" value  any [val ""]]
        ]
    ]


Don't-trace allows you to turn off selected rules that may get called 
a lot. You could also set tracing levels if you wanted.
Gregg:
21-Jun-2009
This makes it easy to test input that doesn't parse and, if I can't 
find the problem or location quickly, turn on the trace and see exactly 
where it fails. 


I've also thought about, and asked Carl for, a way to get the position 
where the parse failed, including a line number.
Izkata:
21-Jun-2009
The main thing I do is, at some point that happens a lot in the code, 
display the data.  Makes it easier to step through the code and do 
- in your head - what the code is doing.  If it suddenly doesn't 
match up, the loic somewhere was wrong.  For example, when working 
on the last one, I had to debug part of it and did this:

parse/all {aX--baX~~a--aX~~aXX~~} [                              
          

   some [                                                           
             

      ["a" S: (? S) some [E: ["--" | "~~"] (print copy/part S E) break 
      | skip] | skip] 
   ]
]
mhinson:
23-Jun-2009
I seem to be going backwards with learning this. Perhaps I think 
I know the grammer, but don't.

I am trying to write out long hand what I want to do, then convert 
it to a parse, but I dont have any words to describe how parse skips 
back to a previous point, so I cant write what I want to do long 
hand either..  e.g. gather the x in pairs from {fd doixx s x x x 
oie    x }

test for "x" or skip  then when x is found do the same thing but 
escape to the outside loop.   

If I could write the above in a format that made more sense I think 
I would have a better chance of then converting it to a parse.

test for "x" or skip seems to be   ["x" | skip]

doing it twice to get the x in pairs would seem like  ["x" | skip] 
["x" | skip] 

but that dosnt work because it lacks the loop control so I add that 
by a bit of guess work because I dont understand it properly.
parse/all data [some[["x" | skip] ["x" | skip]]]

but this is just completly wrong & I think the reason it is wrong 
is because I have completely misunderstood some or skip or | or where 
the point in the string the parse pointer gets to after each step.... 
 I have tried using OPT & break in the second section but just get 
more muddled.
mhinson:
23-Jun-2009
Gregg's suggestion sounds as if it might be helpfull, but I cant 
understand it yet.  Izkata's suggestion is very helpfull, but in 
my case tends to just show that I am miles away from anything like 
a solution.  Thanks.
PeterWood:
23-Jun-2009
MIke, my first advice would be to avoid trying to "go back" during 
a parse operation at this stage. I think that is something to leave 
until you feel more comfortable with parse.
PeterWood:
23-Jun-2009
Perhaps a good starting point is to think that when you "parse" something, 
you are asking does it conform to the rules I have supplied. If it 
does parse returns true, if it doesn't parse returns false.

>> parse "abcdefghi" ["abcdefghi"]

== true

>> parse "abcdefghi" ["abcde"]    

== false
PeterWood:
23-Jun-2009
You're already familiar with to,thru,  end and to end: 

>> parse "abcdefghi" ["a" to "i"]
 
== false
>> parse "abcdefghi" ["a" thru "i"]
 
== true
>> parse "abcdefghi" ["abcde" to end]

== true
PeterWood:
23-Jun-2009
Perhaps the second thing to realise is a rule can be split into "sub-rules':

>> parse "abcdefghi" ["abcde" "fghi"]

== true
PeterWood:
23-Jun-2009
(What Gregg referred to was a much more sophisticated way of getting 
the parse to show you what happened).
PeterWood:
23-Jun-2009
Sub-rules can be optional by using the | (or) and enclosing the options 
in a block:


>> parse "abcdefghi" ["abcde" (print "abcde found") ["fghi" (print 
"fghi found") | "xyz"(print "xyz found")]]                       
                                                   
abcde found
fghi found
== true
PeterWood:
23-Jun-2009
We can specify that a sub-rule should be repeated:


>> parse "abcdefghi" ["abcde" 4 skip] 

== true
PeterWood:
23-Jun-2009
A better example of repetition:

>> parse "aaa" [4 "a"]

== false
PeterWood:
23-Jun-2009
Some and Any are forms of repetition, this shows the difference:

>> parse "aaa1000" [some "a" to end]

== true

>> parse "aaa1000" [any "a" to end] 

== true

>> parse "bbb1000" [any "a" to end]   

== true

>> parse "bbb1000" [some "a" to end]

== false
32901 / 6460812345...328329[330] 331332...643644645646647