World: r3wp
[I'm new] Ask any question, and a helpful person will try to answer.
older newer | first last |
mhinson 4-May-2009 [2111] | I have been working out ways to extract IP addresses from a string today. Is this a good way to do it? What could catch me out? parse to-block "junk 111.111.111.111 0.0.0.0 255.255.255.128 junk" [ any [ set tup tuple! (print tup) | skip ] ] |
Oldes 4-May-2009 [2112] | It depends, what the junk can be.. in your case it must be REBOL loadable. |
mhinson 4-May-2009 [2113] | I was hoping the TO-BLOCK would take care of that. do I need to parse the junk first to remove unloadable strings? or is there another TO- function that will do it for me please? |
Oldes 4-May-2009 [2114] | This should be safe: use [ ch_numbers ch_rest rl_ip ip-start ip-end ips ][ ch_numbers: charset "0123456789" ch_rest: complement ch_numbers ips: copy [] rl_ip: [ ip-start: some ch_numbers #"." some ch_numbers #"." some ch_numbers #"." some ch_numbers ip-end: (error? try [append ips to-tuple copy/part ip-start ip-end]) ] set 'get-ips func [str][ clear ips parse/all str [ some [ any ch_rest rl_ip ] ] ips ] ] get-ips "err,.;s 111.111.111.111 0.0.0.0 255.255.255.128 junk" |
mhinson 4-May-2009 [2115] | Thanks or that snippet, sounds as if you have been on this trail before. Thanks. |
Oldes 4-May-2009 [2116] | sorry.. : some [ any ch_rest rl_ip | skip ] so it handles cases like: get-ips "err,.;s 111.111.111 0.0.0.0 255.255.255.128 junk" |
mhinson 4-May-2009 [2117] | clever, defo better than my simple tuple search. Thanks. |
Oldes 4-May-2009 [2118x4] | and or you can use: get-ips2: func[str /local ips ip][ str: parse str none ips: copy [] while [not tail? str] [ error? try [ ip: to-tuple str/1 if 4 = length? ip [append ips ip] ] str: next str ] ips ] |
BUT in the second version there is problem with cases like: get-ips2 {"this is invisible IP 0.0.0.0" 255.0.0.0} | |
Also it fails with: get-ips2 {this is NOT an IP 255.0.0.} | |
So the result is.. if you want to be sure, use the string based parsing. | |
mhinson 4-May-2009 [2122] | I suppose it depends where the data comes from. looking at configs from routers should mean the IP addresses & masks etc are already propperly formatted. Thanks. |
Pekr 5-May-2009 [2123] | you could also probably enhance it by stati 1 to 3 digitis, dot ... |
mhinson 7-May-2009 [2124] | Hi, I have been working on a bit of code for some time & it now does something usefull for me, but to use it I am coding the output file into the code & running it repeatedly against every file in a directory. I thought it would be nice for it to have a very simple GUI to navigate to the input directory & output file & perhaps display some indicator of progress. Is this something a beginner might hope to add to existing code, or should I start from scratch again with the GUI part, then try to recreate my code in the view Layout part? Thanks. |
Henrik 7-May-2009 [2125] | you can create a prototype of the GUI first, by just creating a layout with the placement of the styles you want. afterwards you can make it work as you want using SET-FACE, GET-FACE, etc. |
mhinson 7-May-2009 [2126] | I will have a fiddle & see if I can understand that. Thanks very much Henrik |
Henrik 7-May-2009 [2127] | It's very easy to create prototypes and VID is excellent for that: view layout [ across space 2 box blue 300x300 "List View" box yellow 100x300 "Buttons" return box red 402x24 "OK/Cancel Panel" ] |
mhinson 7-May-2009 [2128x2] | Thanks, I started looking at this before & got confused with how I extract the information I can see on the screen & use it in the context of another block of code. With VB I think event handelers pop up everywhere? not sure but I think it is something like that. I couldnt work out how the same sort of thing is done in Rebol. |
if I have view layout [box green 400x400 field] the interpreter wont even load any more lines of script while the box is on the screen, so I am guessing I have to call the rest of my code from within the view layout block? | |
Henrik 7-May-2009 [2130x3] | Here's some learning by doing: With the above line of code, activate the console and press escape. The event handler is returned to the console. Now you can control the window interactively. Type UNVIEW. |
Then try this line: view layout [b: box green 400x400 f: field] Go back to console and escape. b/color: yellow show b set-face f "hello" get-face f hide f show f That's how you access UI parts. | |
If you want to return the event handler to the UI, type DO-EVENTS. | |
mhinson 7-May-2009 [2133] | Unview! wow, that will save me exiting the console a hundred times a day!! That is a top tip & should be in a prominate place for newbies. |
Henrik 7-May-2009 [2134] | If you want to show a window and return to console immediately, use VIEW/NEW instead. |
mhinson 7-May-2009 [2135x2] | This might be doable even for me. Thanks for these tips, I have read so much about Rebol, but I never seem to take it in properly. One of the great things with rebol is how I can test even the smallest fragment of code in the console, this makes it very friendly. Thanks for your help. |
I have been looking at the library examples & noticed that some of them start off with something like navigator: make object! [ The ones like this dont do anything so I am guessing I need to use this code in a way I have not come across yet. I have been madley trying things like make a: navigator and looking up make in the documentation, but not understanding the answers. | |
Henrik 7-May-2009 [2137] | make object! is the same as making a context. If you see an entire script wrapped in make object! [] or context [], it is because it was desired to use this script with other scripts without polluting the global namespace. |
mhinson 7-May-2009 [2138] | Oh, I see, the actual functions are inside the object. |
Henrik 7-May-2009 [2139] | Try this: context [ a: 2 set 'b 3 set 'c does [return a] ] >> a >> b >> c A simple way to control what's private and public. |
mhinson 7-May-2009 [2140] | I see, that is good. I have seen the 'b syntax used but not understood it yet. I see in your example the set 'b 3 seems like b: 3 in the global context. Thanks very much for your tips, they are a great help. |
Sunanda 7-May-2009 [2141] | On the other hand, if you want 'a, 'b, 'c to be local to the context -- so other parts of your application can also have their own 'a. 'b and 'c without overwriting each other: my-api: context [ a: 2 b: 3 c: does [return a + b] ] my-api/a: 5 ;; override default value print my-api/c ;; executes function in context |
mhinson 7-May-2009 [2142] | I wondered how the xxx/xxx/xxx paths to data were constructed... I was thinking of this sort of thing as a way to refer to valuse in a multi demensional array by name rather than number house: context [ room1: context [ items: [bed chair table] ] room2: context [ items: [TV sofa HiFi] ] ] |
Sunanda 7-May-2009 [2143] | That's the way I do it, using 'context / make object! Some people prefer using blocks rather than objects: blk: [a 4 b 5 c 6] blk/b == 5 blk/b: 99 probe blk == [a 4 b 99 c 6] There are advantages and disadvantages to each approach. |
mhinson 7-May-2009 [2144] | I used to get the same sort of effect in Pascal by defining ordinal types with values that were meaningfull words & use them to index my arrays. |
Sunanda 7-May-2009 [2145] | :-) ..... You could think of it as a type of associative array. |
mhinson 7-May-2009 [2146] | A question: if I want to provide a dialoge to navigate to a directory can I call up the ms windows file open & save dialogs, or do I have to do it all in rebol. I cant find any examples of this & dont have the skills to create my own... I like the idea of having a GUI interface, but I may have to go back to command line if it is too hard for me :-) |
Sunanda 7-May-2009 [2147] | File open dialog is simple. source request-file :-) |
mhinson 7-May-2009 [2148] | oh, that was simpler than expected. Thanks very much. I must say I dont think Rebol is very easy to learn, but once all these tricks are known it must be very easy to write things quickly. Perl is like a tool shop & a tree for wood, while Rebol is like a high street full of all sorts of shops as well as tools. |
Sunanda 7-May-2009 [2149] | And unexpected pot holes :-) |
mhinson 7-May-2009 [2150] | There is a request-dir too, but it is a bit of a joke. Looks like the way to go is to use the request-file then extract the directory. Why would request-dir even exist in such a feeble state? Sorry, I hope I am not speaking out of turn, but if anyone had that pop up they would think it was a bit odd. |
Sunanda 7-May-2009 [2151] | No, request-dir is pretty low standard. |
Henrik 7-May-2009 [2152x2] | some parts are sub-par, like request-color as well. fortunately it's possible to rewrite them. |
large parts of the GUI system was written in a very short time by Carl alone back early in this decade and has not been officially upgraded. | |
mhinson 7-May-2009 [2154] | Excuseme please, but can someone pull me out of the mud here please? filenames: request-file/title/filter/path {Select all files to read} [*.txt] %/D/Rebol/X/!conf/ What have I not understood this time? Why does the documentation have no examples I can find? Sorry to be always asking :-( |
Henrik 7-May-2009 [2155] | two arguments are necessary for the /TITLE refinement. |
mhinson 7-May-2009 [2156x2] | I added an extra string for the title and now get this similar failure >> filenames: request-file/title/filter/path {Select all files to read} {x} [*.txt] %/D/Rebol/X/!conf/ ** Script Error: Invalid argument: *.txt * *.r *.reb *.rip *.txt *.jpg *.gif *.bmp *.png ** Where: request-file ** Near: done: local-request-file data: reduce [tt/text ob/text clean-path where picked filt-names filt-values found? any [only]... |
AH a string "*.txt" for the filter works Thanks for your help | |
Gregg 11-May-2009 [2158x2] | Large message coming, with examples of showing progress. Note that it uses INCLUDE and FILE-LIST, so adapt accordingly, and let me know if I left any other dependencies in it that cause it not to work. It was quickly hacked from existing code. |
REBOL [] do %include.r include %file-list.r flash-wnd: flash "Finding test files..." if file: request-file/only [ files: read first split-path file ] if none? file [halt] items: collect/only item [ foreach file files [item: reduce [file none]] ] unview/only flash-wnd ;------------------------------------------------------------------------------- ;-- Generic functions call*: func [cmd] [ either find first :call /show [call/show cmd] [call cmd] ] change-each: func [ [throw] "Change each value in the series by applying a function to it" 'word [word!] "Word or block of words to set each time (will be local)" series [series!] "The series to traverse" body [block!] "Block to evaluate. Return value to change current item to." /local do-body ][ do-body: func reduce [[throw] word] body forall series [change/only series do-body series/1] ; The newer FORALL doesn't return the series at the tail like the old one ; did, but it will return the result of the block, which is CHANGE's result, ; so we need to explicitly return the series here. series ] collect: func [ "Collects block evaluations." [throw] 'word block [block!] "Block to evaluate." /into dest [block!] "Where to append results" /only "Insert series results as series" /local fn code marker at-marker? marker* mark replace-marker rules ][ block: copy/deep block dest: any [dest make block! []] fn: func [val] compose [(pick [insert insert/only] not only) tail dest get/any 'val get/any 'val ] code: 'fn marker: to set-word! word at-marker?: does [mark/1 = marker] replace-marker: does [change/part mark code 1] marker*: [mark: set-word! (if at-marker? [replace-marker])] parse block rules: [any [marker* | into rules | skip]] do block head :dest ] edit-file: func [file] [ ;print mold file call* join "notepad.exe " to-local-file file ;join test-file-dir file ] flatten: func [block [any-block!]][ parse block [ any [block: any-block! (change/part block first block 1) :block | skip] ] head block ] logic-to-words: func [block] [ change-each val block [either logic? val [to word! form val] [:val]] ] standardize: func [ "Make sure a block contains standard key-value pairs, using a template block" block [block!] "Block to standardize" template [block!] "Key value template pairs" ][ foreach [key val] template [ if not found? find/skip block key 2 [ repend block [key val] ] ] ] tally: func [ "Counts values in the series; returns a block of [value count] sub-blocks." series [series!] /local result blk ][ result: make block! length? unique series foreach value unique series [repend result [value reduce [value 0]]] foreach value series [ blk: first next find/skip result value 2 blk/2: blk/2 + 1 ] extract next result 2 ] ;------------------------------------------------------------------------------- counts: none refresh: has [i] [ reset-counts i: 0 foreach item items [ i: i + 1 set-status reform ["Testing" mold item/1] item/2: random/only reduce [true false] show main-lst set-face f-prog i / length? items wait .25 ] update-counts set-status mold counts ] reset-counts: does [counts: copy [total 0 passed 0 failed 0]] set-status: func [value] [set-face status form value] update-counts: has [pass-fail] [ counts/total: length? items pass-fail: logic-to-words flatten tally collect res [foreach item items [res: item/2]] ;result (e.g.): [true 2012 false 232] standardize pass-fail [true 0 false 0] counts/passed: pass-fail/true counts/failed: pass-fail/false ] ;--------------------------------------------------------------- main-lst: sld: ; The list and slider faces c-1: ; A face we use for some sizing calculations none ml-cnt: ; Used to track the result list slider value. visible-rows: ; How many result items are visible at one time. 0 lay: layout [ origin 5x5 space 1x0 across style col-hdr text 100 center black mint - 20 text 600 navy bold { This is a sample using file-list and updating progress as files are processed. } return pad 0x10 col-hdr "Result" col-hdr 400 "File" col-hdr 100 return pad -2x0 ; The first block for a LIST specifies the sub-layout of a "row", ; which can be any valid layout, not just a simple "line" of data. ; The SUPPLY block for a list is the code that gets called to display ; data, in this case as the list is scrolled. Here COUNT tells us ; which ~visible~ row data is being requested for. We add that to the ; offset (ML-CNT) set as the slider is moved. INDEX tells us which ; ~face~ in the sub-layout the data is going to. ; COUNT is defined in the list style itself, as a local variable in ; the 'pane function. main-lst: list 607x300 [ across space 1x0 origin 0x0 style cell text 100x20 black mint + 25 center middle c-1: cell cell 400 left cell [edit-file item/1] ] supply [ count: count + ml-cnt item: pick items count face/text: either item [ switch index [ 1 [ face/color: switch item/2 reduce [none [gray] false [red] true [green]] item/2 ] 2 [mold item/1] 3 ["Edit"] ] ] [none] ] sld: scroller 16x298 [ ; use SLIDER for older versions of View if ml-cnt <> (val: to-integer value * subtract length? items visible-rows) [ ml-cnt: val show main-lst ] ] return pad 0x20 f-prog: progress 600x16 return status: text 500 return button 200 "Run" [refresh show lay] pad 200 button "Quit" #"^q" [quit] ] visible-rows: to integer! (main-lst/size/y / c-1/size/y) either visible-rows >= length? items [ sld/step: 0 sld/redrag 1 ][ sld/step: 1 / ((length? items) - visible-rows) sld/redrag (max 1 visible-rows) / length? items ] view lay | |
mhinson 12-May-2009 [2160] | Hi, I am trying to reduce the number of global variables I use in functions & so my functions return blocks, but I have not discovered any simple way to dereference the information in the variables, within the blocks.. I have written a function to do it, but I guess there is a built in function if I could find it. Or at least something a bit more elegant than this: "return_value_of_block_component" function. Any tips most welcome please. f1: func [a] [ b: join a "-Bee" c: join a "-Cee" return [b c] ] d: f1 {Hi} return_value_of_block_component: func [block component] [ foreach element block [ if element = component [return reduce [element]] ] ] H: return_value_of_block_component d 'b I: return_value_of_block_component d 'c print H print I |
older newer | first last |