World: r3wp
[Core] Discuss core issues
older newer | first last |
Pekr 14-Aug-2007 [8619x2] | what do you mean by timing out? |
when you use direct/no-wait, it does not wait. You have to explicitly call wait to get events. Also copying from port does not block ... | |
sqlab 14-Aug-2007 [8621x2] | Hi Joe something like either port: wait reduce [opened-port1 opened-port2 timeout] [ print "data available" probe copy port ] [ print "timeout" ] |
You can also have a look at dispatch | |
james_nak 15-Aug-2007 [8623] | I was wondering if I am going about searching for particular values wrong. If I have a block of objects and I want to search for a particular value within one of those objects should I go though each obj using something like "foreach" or is there a better way. For example movies: [m1 m2 m2] where m1 is an object with a "title" value, etc. foreach movie movies [ if movie/title == "Star Wars" [.....] ] Of course that works but it seems primitive. |
Brock 15-Aug-2007 [8624x2] | I'd be interested in seeing what others do in this situation as well. I believe most people would be using one of the sql options available to clean this up. |
I know there is a sql dialect out there, it would be interesting to know how it performs this type of query. | |
Gregg 15-Aug-2007 [8626] | Don't confuse "primitive" with "simple and obvious". :-) Without trying to avoid answering your question (what you're doing is fine :-), let me ask some questions in return: What is your goal? Do you want to improve readability? Allow users to enter queries? Improve performance? What goes in the [....] block? What would you have to do to perform this task *without* examining each object? |
james_nak 15-Aug-2007 [8627] | Gregg, well in the back of my mind since I started programming with BASIC, C and Assembler (which, without wanting to start an Altme-war, I refer to as 'procedural' as opposed to OO), I was just wondering if there was another "object-oriented" way. You know, like "find" but with special parameters that tell it to do what my "foreach" actually does. I don't know, it just seemed kind of "Dorky." : ) I'm writing an app that will produce php code to help me administer mysql db's. I'm at the point where it can read the table and field data and create objects with that info. Now I'm at the part where it goes back and pulls that data out. So, I've assigned each table an index # then in the "columns" object, it refers back to that index. Since I have a block of those column objects I was just looking for a spiffy way of finding which ones, for example, of finding all of the objects that are part of table index #3. I've always used the "foreach " method but you know, I'm always looking for a way to improve my code. Thanks Gregg for your input. |
Geomol 15-Aug-2007 [8628] | James, are you after a search three? Do you know those data structures? Examples are binary search threes, B-threes, etc. |
BrianH 15-Aug-2007 [8629] | Do you mean tree? |
Geomol 15-Aug-2007 [8630] | Yes, of course! Tree! Sorry about that. |
james_nak 15-Aug-2007 [8631] | Actually I was just wanting to know if I was missing something in the way I am checking for a value within an object that is part of a block of objects. Nothing really sophisticated and these blocks are really small so no need for speed increases. To be frank, I often look at the code you all write and say to myself: " Self, how in the world did they think of that?" or "Oh, I didn't know you could do that." For example when I first started using Rebol, I didn't know about the "in" word as in "Get in object 'word.." so I was always using paths and trying to figure out how one would make the path a "variable." (object/mypath, where mypath could be some changing value). Thanks for your input though. |
Geomol 15-Aug-2007 [8632x2] | Maybe you could make a block with the titles and the objects together, and then just use a path to get to the object? Something like: >> movies: reduce ["Star Wars" make object! [status: 'good!] "Matrix" make object! [status: 'cool]] >> movies/("Star Wars")/status == good! >> movies/("Matrix")/status == cool |
I'm just throwing ideas! :-) Work with it. | |
james_nak 15-Aug-2007 [8634x2] | You see, stuff like that is very interesting to me. |
I didn't know you could use ( ) like that. | |
Geomol 15-Aug-2007 [8636] | I think, we were allowed to use () in paths in recent versions of REBOL. Not exactly sure when. |
james_nak 15-Aug-2007 [8637] | Why doesn't anyone tell me these things? : ) |
Rebolek 15-Aug-2007 [8638x2] | james_nak: http://www.rebol.com/article/0025.html:) |
it's almost three years...time runs so fast :))) | |
Gregg 16-Aug-2007 [8640] | Another thing to consider is that this is a general need, so FOREACH (e.g.) may be used, but you can hide it in a wrapper func, maybe called SELECT-ALL, that works like REMOVE-EACH. I have different variations, based on how other langs do it, e.g. select/inject in smalltalk. Here's a very quick way to leverage REVMOE-EACH. filter: keep-each: func [ "Keeps only values from a series where body block returns TRUE." 'word [get-word! word! block!] "Word or block of words to set each time (will be local)" series [series!] "Series to traverse" body [block!] "Block to evaluate. Return TRUE to collect." ] [ remove-each :word series join [not] to paren! body ] comment { filter x [1 2 3] [x = 2] filter x [1 2 3] [odd? x] filter res [1 2 3] [odd? res] filter [x y] [a 1 b 2 c 3] [all [odd? y 'c = x]] } |
james_nak 16-Aug-2007 [8641] | Thanks Gregg and Rebolek! |
Joe 17-Aug-2007 [8642] | pekr,sqlab, thank you for your answers. I thought that sync ports also had a timeout like the async kernel (set-modes port [timeout: 30]) but they do not. thanks |
Henrik 20-Aug-2007 [8643x2] | I may be the last to learn this, but I didn't know you could do this: >> type? first [none] == word! >> type? first [#[none]] == none! |
which is neat :-) | |
Geomol 21-Aug-2007 [8645] | Any thoughts on this? >> #"a" * 2 == #"Â" >> 2 * #"a" == 194 So multiply is commutative in a 'funny' way. In this example, you get the result in the same datatype as the first argument. This also works: >> #"a" * 2.0 == #"Â" But you can't do: >> 2.0 * #"a" ** Script Error: Cannot use multiply on decimal! value So multiply is not commutative, when it comes to decimals and chars. Any comments? Also think of other datatypes, you wanna multiply. |
Tomc 22-Aug-2007 [8646] | I think I would avoid using that feature often |
[unknown: 5] 29-Aug-2007 [8647] | I once heard that R2 doesn't allow you to free memory and that R3 will. Anyone know if we are able to free memory in R2? I think it was concerning a stats command discussion somewhere. |
btiffin 30-Aug-2007 [8648x2] | Paul; Check http://www.rebol.org/cgi-bin/cgiwrap/rebol/view-script.r?script=free-mem.r for a small blurb and a way to free memory in R2. |
Newer versions of REBOL allow a simple unset 'var recycle sequence. But GC is voodoo a lot of times, not just in REBOL, so there are probably cases that this won't apply. | |
DanielSz 30-Aug-2007 [8650x2] | Hi Rebol community, I was wondering about how you deal with error handling in Rebol in those situations where you have a number of network operations which are likely to fail part of the time. Of course, you already raised the timeout for network protocols (system/schemes/default/timeout: 0:10). Now say your script contains a number of network operations (read url, for example) wrapped in user functions. This is a very common situation. For example: fetch-actual-ip: does [ page: read-url-with-basic-auth http://192.168.1.1/Status.htm(http-basic-auth-key router_username router_password) parse page [thru <td class="stdbold" nowrap> copy ip to </td>] return to-tuple ip ] Now this is fine, but if your read operation fails, the script will abort. You would like the function to try again a couple of times. The first thing you would be tempted to do is to redefine the function to repeat the function in case of error or unexpected result. A recursive function like the next one may provide some solace: fetch-actual-ip: does [ page: read-url-with-basic-auth http://192.168.1.1/Status.htm(http-basic-auth-key router_username router_password) either none? tmp: find/tail page "ip address" [ print "Retrying..." retries: retries + 1 if retries > 10 [print "Retried 10 times. Exiting" quit] fetch-actual-ip ] [ parse tmp [thru <td class="stdbold" nowrap> copy ip to </td>] retries: 0 return to-tuple ip ] ] You might have a number of user functions and each can fail, so transforming every user function into a recursive one with its own error handling block can be tedious. Wouldn't it be better to abstract the process with a meta-function that accepts as input the user function itself? The error handling logic would then be exclusively handled by that meta-function, which will save you from redundancy if you have multiple user functions. Let's do it: retry: func [external_function [function!] retries [integer!] /local .retry [function!] tries [integer!] value] [ tries: 0 .retry: func [.external_function [function!]] [ either not error? try [value: .external_function] [ if not none? value [return value] ] [ print "Retrying..." tries: tries + 1 if tries > retries [print rejoin ["Tried function " tries " times. Exiting"] return] .retry :.external_function ] ] .retry :external_function ] Now you call the short version of fetch-actual-ip like this: retry :fetch-actual-ip 5 (try the user function 'fetch-actual-ip up to 5 times) Anyone wants to comment or improve on this? |
One difficulty is to refine the meta-function 'retry to accept user functions with a variable number of arguments. Tricky. Anyone got an idea? | |
Graham 30-Aug-2007 [8652] | provide the argument list in a block to the retry function |
Gregg 31-Aug-2007 [8653] | It can seem like more work, but and FSM based model works well IMO. |
Louis 31-Aug-2007 [8654x3] | From section 11.12 of the Core users manual: inp: open/binary/direct ftp://ftp.site.com/big-file.bmp out: open/binary/new/direct %big-file.bmp buf-size: 200000 buffer: make binary! buf-size + 2 while [not zero? size: read-io inp buffer buf-size][ write-io out buffer size ;<================<<< Where did size come from; this is incorrect, no? total: total + size print ["transferred:" total] ] |
Whoops! Watch out for wordwrap. | |
Sorry. I see it now. My mistake. | |
DanielSz 31-Aug-2007 [8657] | Exactly, Graham, argument passing in a block is a decent solution. I saw here and there rebol code implementing this for similar purposes. I'll repost a an updated 'retry version when I get around it. |
Louis 31-Aug-2007 [8658] | Attention whoever is in charge of documentation. Section 11.12 of the Core Users Manual give an example that will not work. A clear buffer statement is needed after the write-io line, and the ports need to be closed after sending each file. |
DanielSz 31-Aug-2007 [8659x4] | Gregg, do you mean Finite State Machine. Care to expand? |
Ok, here is an updated version of 'retry. What is it? It is a higher -level function that takes as input a user function and repeats it the number of times specified. The current version handles user functions that take arguments. | |
Usage: retry :user_function 5 For a user function that doesn't take arguments retry/args :user_function 5 [args] For a user function that take arguments retry: func [user_function [function!] retries [integer!] /local .retry [function!] tries [integer!] value [any-type!] args_length [integer!] /args block [block!]] [ tries: 0 args_length: length? first :user_function if ((args_length > 0) and (not args)) [print ["User function require" args_length "arguments. Provide them in a block and use the /args refinement."] return] if not args [args_length: 0 block: []] .retry: func [.user_function [function!]] [ either not error? try [value: do compose [.user_function (copy/part block args_length)]] [ if not unset? value [return value] ] [ print "Retrying..." tries: tries + 1 if tries > retries [print rejoin ["Tried function " tries " times. Exiting"] return] .retry :.user_function ] ] .retry :user_function ] Everybody is invited to improve on this. | |
I wrote 'retry to use in scripts heavy in network calls where failure is, by nature of the internet, common, so instead of aborting when such a failure occurs, I can use 'retry to repeat individual functions any number of times I wish, improving the success of the script. | |
Gabriele 1-Sep-2007 [8663x2] | >> retry: func [code times] [ [ loop times [ [ attempt [ [ break/return do code [ ] [ ] [ ] |
>> retry [1 / probe -1 + random 2] 5 0 1 == 1 | |
DanielSz 1-Sep-2007 [8665x4] | Very elegant, and concise, Gabriele. Maybe you can propise have an expanded version to handle arguments the code should be invoked with |
Sorry, I pressed Enter by mistake, here I go again: Very elegant, and concise, Gabriele. Maybe you can propose an expanded version that can handle arguments that the code should be invoked with. | |
That's what 'retry currently does. | |
If you provide that capabilty, I take your version in no time. Mine is too obscure. | |
older newer | first last |