• 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
r4wp4382
r3wp44224
total:48606

results window for this page: [start: 17601 end: 17700]

world-name: r3wp

Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public]
Pekr:
14-Apr-2009
btw - do you use parse/all? I prefer to use parse with the refinement, 
because using plain 'parse ignores whitespaces, and I don't like 
when the engine messes with things instead of me :-)
sqlab:
14-Apr-2009
I am not sure that I understand your intention.

Do you want just  interface ATM0.1, then you have to switch the order 
of your interface rule, as the condition to  #"^/" (newline)  is 
already true and done, and your cursor behind  "point-to-point".
As the first part is true, the second will never be done.
Pekr:
14-Apr-2009
you can also use rebol and call php or perl for some stuff :-) However 
- you rules could be made - you just need to scatter it into sections 
and find some rules for the parsed file structure.
PeterWood:
15-Apr-2009
In case this isn't clear. I'll try to explain the parse rule.


First any effectively says to match any of the rules in the following 
block until the end of the string is reached.

The first rule in the block is 

 [interface copy int-text some name-char (print ["interface: " int-text)]

says match with the word interface (newline + "interface ")

then if there is a match,  copy some name-char which says copy one 
or more characters which match the criteria of a name-char

then if there are some name-char characters evaluate the rebol code 
in parentheses.


If there wasn't a match with that first rule, then the second rule 
that follows the | will be applied.

skip will pass over one character and always provides a match.
PeterWood:
16-Apr-2009
Mike - The method that I showed you does not use up the "newline" 
at the end of the line. If you check again, the parse rule simply 
says copy in-text some name-char. This "stops" before the newline 
at the end of the line.


In fact guessing at your requirements a little and assuming the name-char 
is available. Some thing along these lines should be close to what 
you want:


keywords: ["^/interface " | "^/another keyword " | "^/yet another 
kerword"]

parse/all lines [any
  [ 
     copy int-keyword [keywords copy int-text some name-char (
       print  int-keyword ": " int-text]
    )
    |
    skip
 ] 
]

{I obviously haven't tested this code.)
sqlab:
16-Apr-2009
I see just two ways to get what you desire

either you define different rules for interface at the beginning 
and interface after newline

or you do it in a two pass way:  first you separate the lines (either 
by parse or by read/lines) and then you process every line by itself.

I would go the easy way with two passes.
Pekr:
16-Apr-2009
uh, was on slow connection, so my reply got lost. Mhinson - there 
is no symbolic way to represent beginning of the line. I don't know 
any in any system. The only thing I know is end-of-line (newline). 
I know what you probably mean - you want to identify beginning of 
your lines, but even for first line (so not a rule, matching newline 
first, then next char = beginning of line). But - there is still 
various ways of how to do it. First - I think that your config files 
are chaos. Do they have any rules for some sections at all? :-) I 
also like what sqlab mentioned - sometimes it is easier to break 
stuff into 2 pass strategy. Read/lines is your friend here. You can 
try it on text files and you'll see, that the result is going to 
be a block of lines. I usually do:

data: read/lines %my-data-file.txt

;--- remove empty lines from block of lines ...
remove-each line data [empty? trim copy line]

foreach line data [do something with data ....]


Simply put - if rules for parser are out of my scope of capabilities 
(which happens easily with me :-), I try to find my other way around 
...
Izkata:
16-Apr-2009
Also, this is a bit slower, but avoids using complicated parse rules:
>> lines: {junk Interface fa0
{    !
{    interface fa1}
== "junk Interface fa0^/!^/interface fa1"

>> SplitLines: parse/all lines {^/}		; {^/} is a string containing 
only the newline character, so this is a list of the separate lines
== ["junk Interface fa0" "!" "interface fa1"]
>> foreach line SplitLines [               
[    if all [                                

[        not none? find line {interface}		;Find returns none! (equivalent 
of NULL or NIL) on "!"

[        head? find line {interface}		;find goes to the first instance 
of what is being searched for, and head? checks if it's currently 
at the beginning of the line
[        ][print line]
[    ]
interface fa1	;The only match
Sunanda:
17-Apr-2009
One huge parse may be technically neat. But it probably does not 
match the real world needs.


Petr's (and other's advice) to break the problem down into managable 
(and separately debuggable chunks) is a good approach.


And, remember, in the Real World, you may also need to track original 
line number (before removal of comments and blanks) to be able to 
give good error messages :  "Bad data encountered near line 12,652"
Geomol:
17-Apr-2009
You can parse strings and blocks. The /all refinement is used when 
parsing strings, not blocks. From your first comments, it seems, 
you're parsing blocks, so you don't need /all. What is lines? A string 
or a block?
Henrik:
17-Apr-2009
the difference between using a set-word and SET word!:

parse [a b c d] [
	w1: word! (probe w1)
	w2: word! (probe w1 probe w2)
	set w3 word! (probe w1 probe w2 probe w3)
	w4: word! (probew1 probe w2 probe w3 probe w4/1)
]
Henrik:
17-Apr-2009
A dialect is just a block of data that is processed in a certain 
way by REBOL. You can't evaluate it directly, but need some kind 
of parser to process it. You can create all sorts of crazy languages 
that way. Both the first and the second arguments to PARSE are dialects. 
The first one is the dialect block you provide to PARSE, the second 
one is the dialect used to process the first dialect. :-)
Henrik:
17-Apr-2009
but unlike other languages that have to use regexp as a crutch for 
parsing, REBOL can use other methods than PARSE to process dialects. 
PARSE is useful in some cases and in other cases, there are better/simpler 
approaches for processing your dialect.
Henrik:
17-Apr-2009
You are in dialect territory immediately when you are defining a 
block of data and wanting to do something other than evaluating it 
with DO.
Henrik:
17-Apr-2009
But in another place, [1 2 3 4] might mean something entirely different. 
It also happens to evaluate as normal REBOL code:

>> do [1 2 3 4]
== 4

But of course it doesn't do much. :-)

Code is data and data is code.
sqlab:
17-Apr-2009
So parse has it's own language, that sometimes resembles to rebol, 
sometimes is different.
And you can make your own languages or dialects too
Henrik:
17-Apr-2009
I know the following sounds basic, but it's _crucial_ to understanding 
how REBOL works, otherwise you will not "get" REBOL:


You must understand the concept that data is code and code is data. 
That means that anything you write, can be considered pure data. 
It's what you do with that data that becomes important.


It's like speaking a sentence, but only paying attention to the placement 
of letters. That makes the sentence pure data. If you then pay attention 
to the words objectively, they can form a sentence, so you can validate 
its syntax. If you use the sentence in a context, you can apply meaning 
to it, subjectively. If you switch the context, the sentence can 
mean something entirely different.

This is very important. Context and meaning.

For REBOL:

[I have a cat]


This is a block with 4 words. It's pure data that can be stored in 
memory, but at that level it doesn't make any sense to REBOL.


If you then apply a function to that data, you can process it. DO 
processes that data as REBOL code. It will be evaluated as REBOL 
code. Here it will produce an error, because it's not valid REBOL 
code. If you produce your own dialect, for example with PARSE, you 
can make that block make sense.


When typing in the console, REBOL evaluates it as normal REBOL code 
by using DO internally. That means:

>> now
== 17-Apr-2009/18:13:14+2:00

is the same as:

do [now]

But this block:

[now]

is just pure innocent data with no meaning.
Brock:
17-Apr-2009
7.4 Marking Input:

  in the link provided by sqlab explains the use of set-words in the 
  parse dialect.  I needed to use this technique to strip out large 
  comments from web logs that I was parsing and passing into a database. 
   I was able to remove the large comment and replace it with a default 
  string indicating "comments have been removed"
Brock:
17-Apr-2009
This way you are only dealing with a small amount of data for each 
parse and might make it easier to visualize for you.
Pekr:
17-Apr-2009
mhinson: now my explanations to some of your questions, as I think 
not everything was explained to you properly:


1) parse/all - /all refinement means, that string is parsed "as-is", 
because without the /all, white-space is skipped:

>> parse "this white dog" ["this" "white" "dog"]
== true
>> parse/all "this white dog" ["this" "white" "dog"]
== false
>> parse/all "this white dog" ["this" " " "white" " " "dog"]
== true

I prefer to always use /all refinement for string parsing ...


2) i don't understand why there is | before "some", that code will 
not work imo ...


3) "ifa:" is a marker. Think about parse in following terms ... you 
have your data, here a string. Parse is the matching engine, which 
tries to match your input string according to given rules. In parse 
context (dialect) you have no means of how to manipulate the input 
string, except the copy. So markers are usually used, when you want 
to mark some position, then do something in parens, and then get 
back the position, or simply mark start: .... then somewhere later 
end: and in the paren (copy/part start end) to copy the text between 
the two marked positions ...


4) "skips till one of the OR conditions are met" - very well understood 
...


5) Here's slight modification for append/only stuff. Type "help append" 
in the console. /only appends block value as a block. You will understand 
that, once you will need such behaviour, so far it can look kind 
of academic to you :-) I put parens there, to make more obvious, 
what parameters are consumed by what function ....

>> wanted: copy []
== []

>> append  (append wanted (copy/part "12345" 3))  interf:  copy ["abc"]
== ["123" "abc"]
>> wanted: copy []
== []

>> append/only  (append wanted (copy/part "12345" 3))  interf:  copy 
["abc"]
== ["123" ["abc"]]
Henrik:
19-Apr-2009
it would be interesting if the config file could be loaded, by making 
unloadable parts like $FW_OUTSIDE$ loadable using simple string replacable. 
Then you could just 'load the file into a block and it would be considerably 
easier to parse.
Steeve:
19-Apr-2009
Pekr, I'm just disapointed by what mhinson produced after getting 
so many advices from Rebolers like you.

The read/line trick is very useless, why doesn't he use the standard 
way of traversing newlines with parse ? 
And why using code (inside parents) to manage optional rules.

Are commands like SOME, ANY, OPT not enough to manage simple rules 
like that ?
Henrik:
19-Apr-2009
I don't yet understand why a block would be easier to parse than 
lines, by easier do you mean more efficient or easier to create the 
code?


Yes, it's easier, because REBOL is based around this concept. Without 
this concept, dialects wouldn't make much sense. Your configuration 
file shown above is a good candidate for a dialect with some tweaks.


I suggest, you read again what I wrote above about the basics of 
words, context and meaning. I can't emphasize enough how important 
this is to REBOL and especially for block parsing. It's important 
to understand this before moving on, or REBOL will remain difficult 
to use for you. Or drop your parse project for now and stick with 
the basics until you understand more of REBOL.

is there a list of things I can't expect to load?


The LOAD function will error out, if a string (such as a file you 
read) can't be loaded into a block of data. 

Try these in the console, and see which ones work:

load "hello"

load "hello,"

load "hello."

load "%"

load "1 2 3 4"


load "hostname pig interface Null0 ! interface Loopback58 description 
SLA changed this"

load %/c/temp/cisco.txt
sqlab:
19-Apr-2009
I am against loading this configuation files. Why?
-you can not control what is inside 
we know already, that there are elements unloadable by Rebol
and the description almost always needs string parsing 

What would I change?

I would either use only one temp variable in the parse rule and after 
just set to the new variable, as there is already a copy involved 
 or I would use a meaningfull variable name in the first place
mhinson:
19-Apr-2009
Good point about my temp1 temp2 etc. that was sloppy.

It is true I cannot control what is inside the config files. They 
can contain any printable chars (eg in encrypted password fields 
or remarks/descriptions or embedded TCL code) and sometimes I am 
going to want to capture that text. 

I don't mind trying to do both methods as it will help me learn. 
Since I can't load the file directly I am thinking I will need to 
do a read %file.txt & replace the /\,[]%$()@:? with %xx etc.  then 
load the result?   I cant find a list of all the chars that I would 
need to treat like this yet.

Henrik, I do continue to read what you have written, it is helpful 
& I think I am beginning to appreciate the concepts. I am probably 
not as clear as I should be about the specification of what I am 
trying to do so the code has tended towards listing the requirements 
rather than being elegant.  Thanks /\/\
mhinson:
19-Apr-2009
Thanks.  These files are getting better with more recent versions 
of Cisco IOS but sometimes trial and error is the only way to find 
the formats used.
mhinson:
19-Apr-2009
I am still new and confused.   where can I read about how to do this 
please?
file: "%file.txt"
host: "Router1"
interface: "fa0"
i: 25
description: []
ipaddr: "1.1.1.1 255.255.255.0"


write/append/string %/c/temp/result.log [file tab i tab host tab 
interface tab description tab  ipaddr newline]


I want the output file to be a tab-seperated set of values but all 
I get is the text 
filetabitabhosttabinterfacetabdescriptiontabipaddrnewline
Graham:
19-Apr-2009
should that be a function and not just a block?
Steeve:
19-Apr-2009
What the need of flags and splitted lines, uh ?
you can't write simple semantic ?
Reading, your example file , you've got these simple rules.

1/ counting the lines
line: [ thru newline (n: n + 1)]


2/ one interface mays contain several lines (infos) and is terminated 
by a line beginning by "!"  
interface: [
	"interface" copy interface* line 
	any [infos | #"!" line break]
]

3/ infos may be description, ip-adrr, ip-tables
infos: [
	  " description " copy desc* line 
	| " ip route " copy route* line
	| "ip address" copy ip-add* line 
]

That''s all folks, just parse the whole file with:
parse/all [any [interface | line]]


Please don't use read/lines or internal flags for such simple rules.
mhinson:
20-Apr-2009
Thanks for pointing out the errors.


The lines I want to group together are not all together in the file. 
But for the interface details they are.

IP routes are grouped together under a vrf & the interfaces will 
relate to a particular vrf.

The end of a section might be a "!" or might just be the beginning 
of the next section, or any non space or anything  that does not 
match a pattern.. It depends on the particular section.


I will try to reduce the number of rules I need and get a very clear 
view of what I am trying to achieve. I don't find the semantics of 
this very easy to grasp and I am still struggling to find any documentation 
that makes sense to me.


Sorry to be asking so many questions but I not done any programming 
to speak of since Pascal the mid 1980s so I am sort of like a complete 
idiot as you see.  Thanks for taking the time to suggest how much 
improvement is possible.
BrianH:
20-Apr-2009
Try passing the string to TO-REBOL-FILE and then that will let you 
specify filenames with local file syntax.
Oldes:
20-Apr-2009
Instead of:
  filename: none
  attempt [ filename: to-file system/options/args]
  if none? file-name [print "Bad command line" halt]
I would use:
if error? try [filename: to-file system/options/args][
	print "Bad command line" halt
]

I really don't like that people use the attemp in cases where they 
expect error. I use own attempt in cases where I don't expect error 
but still want to continue with execution (display and log the error).
mhinson:
21-Apr-2009
That is very good and usefull thanks.  Is there any way to get help 
on things like 

view layout [ slider ]   please.   I am paticularly keen to find 
how the data is returned from these controls.  something like

view layout [ h2 slider ]   but that dosn't work..  there are hundreds 
of examples of how pretty the vid functions are, but I have failed 
to find much about using the results returned.
Geomol:
21-Apr-2009
Now I both mention face and style. Styles are used to create faces. 
I guess, the GUI docs are not too clear in all of this.
Henrik:
21-Apr-2009
LAYOUT is the VID dialect, which is REBOL's layout engine. When giving 
it a block of words, it produces a tree of objects, that each are 
a face. Each face contains sizes, offsets, colors, texts, event handlers 
and actions to perform when clicking on the face.
Henrik:
21-Apr-2009
whoa, Anton is showing expert stuff there. it really should not be 
necessary to work with faces at that level. try settling for VIEW, 
LAYOUT, SET-FACE and GET-FACE for now. The next level would be events 
and the FEEL object. Then possibly STYLIZE.
Henrik:
21-Apr-2009
but note that VID is lacking a lot in some areas, and that requires 
expert supervision (like Anton) to extend. it's excellent for smaller 
projects, though.
Sunanda:
21-Apr-2009
This is a good tutorial, with examples of entering values, and the 
script responding to them:
http://www.rebol.org/art-display-article.r?article=pfx654q
Sunanda:
21-Apr-2009
and:
http://www.rebol.org/ml-topic-index.r?i=vid
Henrik:
21-Apr-2009
mhinson, have you tried running that line of code? Have you noticed 
that everytime you type something and press enter in the field, the 
contents is printed in the console?
mhinson:
21-Apr-2009
I have just realised that in your line of code "field" is the name 
of one of the VID functions, so I understand that one now, thanks.
If I use 
view layout [button "Ok" [name: get-face face print name]]  

it just  returns "none", not down or up or true or false or clicked 
etc. 
I tried this
view layout [button "Ok2" [name: value print name]]
and it returns the text on the button
does this mean get-face does not work on button?
could I have predicted this?
If I try to reference a different value like this
view layout [button "Ok2" [name: value/text print name]]

I just get an error & I have to restart the console to close the 
button.
is this where I should be able to interpret 
print mold system/view/vid/vid-styles/button/feel

to know how to ask for the parts of the value?      Thanks very much 
for all the help.  I am back at work now so can mostly only study 
this in the evenings.
Henrik:
22-Apr-2009
mhinson, you've stumbled onto the first limitation. If we take the 
line of code apart, it does the following:

view								; view the created layout

 layout							; create the layout (object tree of FACES) from the 
 VID dialect block
		[						; start of VID dialect block
			button					; the first element, a BUTTON
				"ok"				; the text for BUTTON

    [				; start of the action block for the button. it's evaluated when 
    the button is clicked.

     name: get-face face	; get the value of the button through the buttons 
     GET-FACE accessor
					print name		; print the value (likely none)
				]				; end of action block
		]						; end of layout block


Now when I say limitation, it's because you can't easily check for 
mouse button up, release, mouse movement, etc. The VID dialect directly 
uses a block right after the button description to describe what 
should happen after clicking the button. That's part of the syntax 
and above I wrote it as:

	<face style> <face text> [<action>]


You can specify size, color, edge size, background image and a few 
grahpical effects.


And with it being a dialect, you can leave things out or swap the 
ordering of some parameters.


If you want more advanced control, you need to use the FEEL object, 
but you are definitely not ready for that. :-) Settle for working 
with VID and some layouts like above. VID was designed to be easy 
and very fast to use. If you go beyond VID, you will need a whole 
lot more knowledge on how to do things.
Henrik:
22-Apr-2009
And if you type:

? b

You get the entire content for that button face.
mhinson:
22-Apr-2009
AH, this is a bit of a revelation..  Now I know where to find all 
those values.
And I can use this sort of construct
view layout [b: button "Hello!" [b/text: "goodbye"]]
Thank you thank you  thank you very much.
Henrik:
22-Apr-2009
with that line, you need to know about SHOW and HIDE. If you set 
b/text like that, you need to do a:

show b

afterwards, or the face won't update.
Sunanda:
22-Apr-2009
I think it's fair to say that VID and VIEW are built on top of the 
REBOL Core. They are not intimately part of REBOL itself, and may 
not always have had the same care lavished on them as the core of 
the language.

So they tend to be a bit messier and fragmented. More of a work in 
progress than an attempt at the state of the art.
Anton:
22-Apr-2009
To leave a trail, you could append to the draw block (without setting 
it to a new block each time, as you've done above), but that would 
mean your draw block would get very big over time.

So a better thing to do is to draw onto an image!, which serves as 
a cache of your previous draw commands. For this, you can use an 
IMAGE instead of a BOX, and use the DRAW function to draw permanently 
onto the image. (The IMAGE style is very similar to BOX, but its 
'image facet is set to an image! for us, ready to use.)
Anton:
23-Apr-2009
The difference being we are using another word (IMG) to reference 
the image!, and the draw block (DRAW-BLK) is not created new each 
time, it is reused. Only the third value in the draw block is modified. 
That could become significant with large draw blocks.
Anton:
23-Apr-2009
I advise you to review each facet in the face object:

	print mold first system/standard/face

and compare with the slightly larger vid-face:

	print mold first system/view/vid/vid-face


(Note, here FIRST is being used to return just the words of an object!, 
without their values. If you just probe a face it will fill up your 
console...)
Anton:
23-Apr-2009
Once you find a specific facet you are interested in, you can then 
probe it to see its value:

	print mold get in face 'color  ; == 200.200.200


and you can do this, of course, with any face you make, such as the 
BOX above.
mhinson:
28-Apr-2009
Hi, I have continued to re-read the documentation for REBOL, and 
appreciating it more as I understand a bit more.

Are there any puzzels I could try to write a solution to, in REBOL, 
that would be good for a beginner please?
Brock:
28-Apr-2009
There is a puzzles group, and the corresponding puzzles answers group. 
 However, I don't believe the puzzles are easy.
ChristianE:
28-Apr-2009
Definitely these puzzles aren't for beginners. But have you already 
had a look at the cookbook at http://www.rebol.net/cookbook? That 
might be a good start trying to understand some of the examples there 
and go on from there ...
Sunanda:
29-Apr-2009
And here's another one. In both cases, there were excellent procedural 
solutions and parse-based solutions.
In both cases, the parse-based solutions were much faster:
http://www.rebol.org/ml-display-thread.r?m=rmlPCJC
Maxim:
29-Apr-2009
the get  function evaluates a word and returns its value, 

the reduce function evaluates a block and leaves all the results 
within the block
Maxim:
29-Apr-2009
in rebol, words are both litteral values and references to values. 
  a word can also be unbound, in which case it essentially refers 
to no value.

and dont kid yourself, this isn't as basic as you'd think  :-)  
I still get bit, even fater years of rebol experience  :-)
Sunanda:
29-Apr-2009
It works, and it is more compact than my original -- so lots of bonus 
points there.


It's worth reading on to look at some of the other procedural solutions, 
and Joel's analysis. That'll give you some good tips on how to solve 
a problem like this using  REBOL's data manipulating tools.

The parse solutions then take it to another level :-)
mhinson:
29-Apr-2009
I still dont feel up to the parse version of the first puzzel, so 
I have had a go at the first part of the second puzzel.  I think 
I am a bit confused about where to use var: 0 
var: copy 0

I have also got a bit mixed up with the use of global variables which 
I know is bad.  This is the code, which now dosnt seem to work since 
I put the variable initalisation inside the compress function, and 
tried to pass the variables to the function.. Dont laugh, but this 
is about 3 hours work.

raw-data: [1 2 3 10 11 99 101 2000 2001 2002 2003 2004]

sequence-break: func [count store result][
	if/else (count > 1) [
		append result to-pair rejoin [store "x" count]
		count: 1
	][
		append result store
	]
]


compress: func [raw-data][count: 1 store: reduce raw-data/1 result: 
[]
	repeat i ((length? raw-data) - 1) [
		if/else ((raw-data/(i) + 1) = (raw-data/(i + 1))) [
			count: count + 1 
		][
			sequence-break count store result
			store: reduce raw-data/(i + 1)
		] 
	] sequence-break count store result
]

probe compress raw-data


I am happy if my code is functional & easy to maintain at the moment. 
 I will never be an application developer but using small bits of 
code to increase personal productivity is IMHO a very worthwhile 
thing to try and do.
Maxim:
29-Apr-2009
I'll just note that you should use either instead of if/else  ... 
the later is deprecated and slower
mhinson:
29-Apr-2009
Thanks for the tips, so either exactly replaces if/else

and I need to initalise series types with var: copy [] but not other 
types.   

These tips are great.. I just need to study it more & I shoud find 
my own bugs (and probably remember them too)  Thanks very much
Sunanda:
30-Apr-2009
We were all newbies once! And we all are again every time we start 
learning something new.


I just remembered another puzzle/challenge I presented to the Mailing 
list, and got back a rich range of replies. This one is purely parse 
(including my first attempt), so trying it out, and then looking 
at others' code can help understand parse. As with the other two, 
it is based on a real-world need, rather than being a textboox exercise. 
(You experience the results of all three puzzles whenever you browse 
wwwREBOL.org).

Good luck with this one too!
http://www.rebol.org/ml-display-thread.r?m=rmlGPGQ
Sunanda:
30-Apr-2009
And, just in case you had any more spare time in the next month, 
another one that really surprised me as being amenable to a parse 
solution:
http://www.rebol.org/ml-display-thread.r?m=rmlJNFC
Maxim:
30-Apr-2009
the ==3 printed is because 

>> probe funcA 2 3


doesn't grab any argument, so it evaluates funcA, evaluates 2, evaluates 
3 and the console prints the last evaluation, so the would be 3.
Sunanda:
30-Apr-2009
Regarding the many ways of creating a function.


I always use 'func .... Life just seems too short to bother with 
the 'does and 'has shortcuts....The result of them is a standard 
function anyway.


So, for me, the choice is between 'func and 'function. I've made 
the choice to use 'func, but I would have been just as happy to use 
'function. It's a personal preference about how local variables are 
specified:
    f: func [a /local b][b: join a a return b]
    f: function [a][b][b: join a a return b]


(though I may change my choice if I were dynamically creating functions 
rather than typing them :)
mhinson:
30-Apr-2009
I was expecting 
funcA to be passed the values 2 & 3 
funcA refer to them as argZ & argY

FuncA to use local variables argA & argB & these variables to be 
given the content of argZ & argY
funcA calls func1 and passes it values in argZ & argY
func1 recieves values passed and refers to them as arg3 & arg4

func1 uses local vars arg1 & arg2 which are given the content of 
arg3 & arg4

func1 swaps position of values in arg1 & arg2 (so we know the function 
has worked)
arg3 & arg4 are given the values of arg1 & arg2

func1 ends and passes the changed content of argZ & argY back to 
funcA that called it, but as argA & argB
The end part of my code is wrong..  it should be 
argZ: argA argY: argB 
reduce [argZ argY]

so expecting argZ & argY to takeon the content of argA & argB

finaly passes the content of argZ & argY back to where it was called 
so the probe shows the swapped values.
Izkata:
30-Apr-2009
Both functions use pass-by-value, so they can't affect the variables 
outside of themselves using internal references.
And, nothing is being done with what func1 returns:
>> func1 2 3
== [3 2]

Try this:
funcA: func [argZ argY /local argA argB][
    argA: argZ                               
    argB: argY                               
    probe Retval: func1 argA argB            
    argA: Retval/1                           
    argB: Retval/2                           
    reduce [argA argB]                       
]
>> funcA 1 2                                
[2 1]  ;printed by the "probe"
== [2 1] ;returned from the function
Izkata:
30-Apr-2009
In this case, the value passed into f2 is a string!, a subset of 
series! (block!, file!, and a couple others are also series!).  Series! 
values are the equivalent of pass-by-reference, like how passing 
an array as an argument in C is pass-by-reference (or similar to 
it...  I forget the exact terminology).

Append works by modifying a series! without creating a new one.
Henrik:
30-Apr-2009
It is very fundamental yes. You must see it as such: REBOL is very 
economical. It will aggresively reuse blocks and strings when it 
can.
Henrik:
30-Apr-2009
And so if you specifically want to keep a series from being changed 
by some operation, you must copy it.
Henrik:
30-Apr-2009
If you know when REBOL reuses series, you can make quite memory efficient 
and fast code.
mhinson:
30-Apr-2009
ah.. this is good stuff.. And this (as expected) does NOT add 1 to 
dat5 each time it is called.
dat5: 5
f5: func [dat5][
	dat5: dat5 + 1
	return dat5
]
print f5 dat5
print f5 dat5


I get it now, I just need to know how to recognise my types accurately.
Henrik:
30-Apr-2009
Another important point: In the context of your function above, it 
doesn't actually matter whether the input is global. This is because 
REBOL works more on a basis of context rather than locals and globals. 
Locals and globals are probably what you are used to from other languages, 
but in REBOL that functionality is achieved through contexts. If 
the content of the context is allowed to survive, the content will 
survive. 

Try:

boo: func [/local pond] [
  pond: []
  append pond 'fish
]

>> boo boo
== [fish fish]
>> boo
== [fish fish fish]

No globals. :-)
Henrik:
30-Apr-2009
Because the contents of a function is really a context, and once 
that function is created, it doesn't disappear, including the blocks 
and series that are existing in that function. (We have to be careful 
here about using the word "context" to describe what we say, and 
the concept of "contexts" in REBOL. Don't mix it up.)
Henrik:
30-Apr-2009
The document you link to is exactly that phenomenon. It's both fundamental 
and very useful in REBOL for many things.
Gregg:
1-May-2009
If you want to be non-greedy, you may need to use alternate rules 
and skip. e.g.

s: {randomXXXrandom.log XXXrandom.txtrandom}
parse/all s [
    any [
        "XXX" mark-1:
        | [mark-2: ".txt"] (
           if all [mark-1 mark-2] [print copy/part mark-1 mark-2]
        )
        | skip
    ]
]
Maxim:
1-May-2009
I was used to regexp, when I used to program in python in particular, 
and that probably is one of the reasons I had soooo much of a hard 
time grasping parse (even after years of trying)
Gregg:
1-May-2009
Yes, parse and regex are more different than alike. Parse is not 
designed to be concise. :-)
Maxim:
1-May-2009
mike: the best tip I can give you is to picture a cursor in your 
head when you type your rules.  parse really is about iterating over 
a series on byte at a time and matching the next expected characetr.
Maxim:
1-May-2009
whenever it doesn't find what it expects, it "rolls back" to the 
last complete finished rule and tries the next one, if an alternative 
was given.  this is hiercharchical.  so if youre inside the 15th 
depth of parse ans suddenly an unexpected character is encountered, 
you might roll back up to the very first rule!
Maxim:
1-May-2009
since it only moves forward, its very fast.  in order to do look 
ahead assertion and things like that (which are slow in regexp anyways) 
you must learn a few tricks in order to manually set and retrieve 
the "current" character index.
Maxim:
1-May-2009
also note that when there is a "roll back", the cursor and rules 
rolls back together.  (unless you are doing manual cursor manipulation 
tricks)
Maxim:
1-May-2009
so if your first rule only matched 2 characters, the second one fails, 
and other alternative is given... the alternative effectively starts 
checking at character 3
Graham:
1-May-2009
I presume that .txt is not going to appear in the 'random' text?? 
 And XXX is really a fixed set of characters?
PeterWood:
2-May-2009
I usually adopt a different approach which is to write a rule to 
match my target and use any and skip to apply that rule progressively 
through the input. It may not be the fastest way but it seems easier 
to grasp than backtracking.

>> haystack: {randomXXXrandom.log XXXrandom.txtrandom} 
>> alpha: charset [#"a" - #"z" #"A" - #"Z"]  

== make bitset! #{
0000000000000000FEFFFF07FEFFFF0700000000000000000000000000000000
}
>>   digit: charset [#"0" - #"9"

]
== make bitset! #{
000000000000FF03000000000000000000000000000000000000000000000000
}

>>   alphanumeric: union alpha digi

t
== make bitset! #{
000000000000FF03FEFFFF07FEFFFF0700000000000000000000000000000000
}
 
                             
>> needle: ["XXX" some alphanumeric 
".txt"]    

>> parse/all haystack [any [copy result needle (print skip result 
3) | skip]]

random.txt

== true


As you can see with this approach, you have to manually extract the 
"XXX" once you've grasped the needle.
Sunanda:
2-May-2009
And this gives you easy access to many useful mailing list threads 
-- often containing "worked examples" in answer to specific problems:
http://www.rebol.org/ml-topic-index.r?i=parse
Pekr:
2-May-2009
to "b" | to "y" might not work as you would expect though. Better 
check what you are expecting, because you should really read it as 
- try to locate "b", and in the case you will not find it, try to 
locate "y". It simply does not mean find first occurance of "b" or 
"y", return the first match ...
Pekr:
2-May-2009
Such functionality is long time request to parse enhancement, and 
is planned to be implemented ...
mhinson:
3-May-2009
Hi, I have been studying the example from Pekr and developed the 
following addaptation.

b: [to "bb" break]
y: [to "yy" break]

parse/all {zyybbc} [ some [b | y  break | skip] copy result thru 
"c"  (print result) ]


however this seems to loop for ever, but I don't understand why. 
Any wise words would be appreciated.  Sorry to be so needy, I am 
begining to wonder that as I am having so much trouble with this 
basic stuff, perhaps this is a programing language that I am just 
not suited to?  Let me know if I am causing a problem by posting 
here so often & I will admit defeat with the parsing & go back to 
something more familiar.s
Maxim:
3-May-2009
mhinson... for backtracking, at least in my experience, using to 
and thru are pretty dangerous... its pretty much the same as using 
a goto within structured programming.
Maxim:
3-May-2009
I find that there several types of broad parse rule families.
-some find and extract values OUT of some arbitrary string.

-some are used as advanced controled structures, where you can pretty 
much simulate lisp functional programming,
-some are used to convert data streams

-others simply can match a whole data set to make sure it conforms.
(+probably others)


strangely each type of setup has sort of a different global approach, 
but its very case specific obviously.
Maxim:
3-May-2009
where as in at what point in the string AND where in the sense of 
a what step are you now in the parsing.
Maxim:
3-May-2009
lesson one, find text AFTER some identifiable (and unmistakable) 
token:
Maxim:
3-May-2009
yes, and at least one rule must match or else it fails and rolls 
back to parent. rule
Maxim:
3-May-2009
some will loop over and over until ALL rules fail. if that happens 
then IT fails too.
Maxim:
3-May-2009
every other time (including after it matched the tag) the second, 
alternative, rule matched, and we where able to hit the end of the 
string.
[unknown: 5]:
3-May-2009
the thing to know about parse mhinson is that you want to set forth 
the righ  matching conditions to get to the end of the string that 
your parsing because if something doesn't match it will abort at 
that point and return false.
Maxim:
3-May-2009
the "comprehension" of those simple things is essential, simply knowing 
about them is useless... cause in real life, you will have to "SEE" 
the whole recursive structure of the parse rules played in your head. 
 


if you don't fully grasp what is going on, you can't really create 
that essential mental map.   that is what kept me from understanding 
parse for 6 yess... SIX years :-(   and suddenly over the course 
of 2 days, I finally "GOT" it and a week later I was building a 700 
line parse rule for a real-time server doing signal convertion from 
one data format to another through two network ports.
Maxim:
3-May-2009
its funny cause once you "get" parse... just about every data manipulation 
is really easy using it.  remark, used find and copy and shit like 
that before... it was a horrendous 100 lines of code.


it was replaced by 10 lines of parse code and now runs 20-50 times 
faster and can do much more funky stuff on top of it.  :-)
[unknown: 5]:
3-May-2009
Yeah Maxim, my mind trys to believe something should be possible 
with parse and I always hit that roadblock when it isn't.
mhinson:
3-May-2009
Ah, so Paul wants to create in effect a "regular expression" and 
use it in the parse.
17601 / 4860612345...175176[177] 178179...483484485486487