World: r3wp
[!REBOL3 Schemes] Implementors guide
older newer | first last |
Graham 13-Aug-2010 [2177] | Let me rephrase that .. you can't define an actor if that word is already in use |
Pavel 13-Aug-2010 [2178] | What? that is exactly what Steeve does if I understand |
Graham 13-Aug-2010 [2179] | which actor is that? |
Pavel 13-Aug-2010 [2180] | the funtions defined in actor object aren't actually actors? |
Graham 13-Aug-2010 [2181x3] | ;** MISSING !!! native FOREACH has not port! as parameter |
so they can't be used actors | |
You can use them as local functions .. just not as actors | |
Steeve 13-Aug-2010 [2184] | the allowed actors are the function with port! as parameter |
Andreas 13-Aug-2010 [2185] | action!s, to be precise |
Graham 13-Aug-2010 [2186] | and if they don't take a port, you can't use them without redefining their behaviour |
Pavel 13-Aug-2010 [2187] | ok i'll try to understand :-( my scheme works used port: open rif:// ... read/seek port 1 but don't work the easy way: read rif://data/file 1, cant access locales |
Andreas 13-Aug-2010 [2188x2] | locales? |
you can easily make `read/seek rif://data/file 1` work, by creating a custom open? actor and using that in your read actor | |
Pavel 13-Aug-2010 [2190x2] | I use locales to stor opened files (I need two files ) |
Andreas any simple example of open? ? | |
Andreas 13-Aug-2010 [2192] | Assuming you store port-local state in port/state, you can simply check port/state for not being none. |
Pavel 13-Aug-2010 [2193] | isn't it the right way? : actor: [ open: func [port [port!] /local path ] [ parse port/spec/ref [thru #":" 0 2 #"/" path:] append port/spec compose [path: (to-file path)] port/locals: [] either (0 = length? port/locals) [ append port/locals open/seek rejoin [port/spec/path ".dat"] append port/locals open/seek rejoin [port/spec/path ".idx"] ][ port/locals/1 open/seek rejoin [port/spec/path ".dat"] port/locals/2 open/seek rejoin [port/spec/path ".idx"] ] return port |
Andreas 13-Aug-2010 [2194x2] | you'll most likley want `port/locals: copy []` |
but based on that, your open? actor would simply be: `open?: func [port [port!]] [not none? port/locals]` | |
Pavel 13-Aug-2010 [2196] | OK I'll try it |
Gregg 13-Aug-2010 [2197] | 0 = length? port/locals can be empty? port/locals |
Andreas 13-Aug-2010 [2198] | and in your read actor, you'll then simply do: either open? port [{read was invoked as `open rif:// + read`}] [{read was invoked directly as read rif://}] |
Pavel 13-Aug-2010 [2199x2] | >> read/seek rif://data/file 1 ** Script error: cannot access locals in path port/locals/2 ** Where: Get-RIF read ** Near: Get-RIF port number |
OK andreas | |
Andreas 13-Aug-2010 [2201x3] | Maybe also a simple `if not open? port [open port]` will suffice in your case. |
(Within the read actor.) | |
But typically you'll also want to add code to close the port again, afterwards. | |
Steeve 13-Aug-2010 [2204] | can't you paste the whole code somewhere ? |
Pavel 13-Aug-2010 [2205] | This automatic open close is not clear to me after Andreas there is no such automation? where is the magic? :-O |
Andreas 13-Aug-2010 [2206] | There is no magic. |
Pavel 13-Aug-2010 [2207] | Rebol [ file: %prot-rif.r title: "RIF protocol" author: "Pavel" rights: 'PD date: 13-Aug-2010 ] ;; Local functions Append-RIF: func [port [port!] record [binary!] ][ write/append port/locals/2 to-binary length? head port/locals/1 ;index port the end of data file will be beginning of new record write/append port/locals/1 record ;data port new record into data file return shift length? head port/locals/2 -3 ;number of records 8 bytes per record ] Get-RIF: func [ port [port!] i [integer!] /local numentry indexpos recpos recend value ][ numentry: shift length? head port/locals/2 -3 ;number of records 8 bytes per record if any [i = 0 i > numentry] [return none] ;numbering starts at 1 ends at file end indexpos: multiply subtract i 1 8 ;compute index offset recpos: to-integer read/seek/part port/locals/2 indexpos 8 either ( (8 * i) = length? head port/locals/2 ) [ ;last record special case recend: length? head port/locals/1 ][ recend: to-integer read/seek/part port/locals/2 add indexpos 8 8 ;internal record ] return read/seek/part port/locals/1 recpos subtract recend recpos ] ;; Scheme definition make-scheme [ name: 'rif title: "RIF Protocol" spec: make system/standard/port-spec-head [] awake: none actor: [ open: func [port [port!] /local path ] [ parse port/spec/ref [thru #":" 0 2 #"/" path:] append port/spec compose [path: (to-file path)] port/locals: copy [] either (0 = length? port/locals) [ append port/locals open/seek rejoin [port/spec/path ".dat"] append port/locals open/seek rejoin [port/spec/path ".idx"] ][ port/locals/1 open/seek rejoin [port/spec/path ".dat"] port/locals/2 open/seek rejoin [port/spec/path ".idx"] ] return port ] close: func [port [port!]] [ foreach port port/locals [close port] ] read: func [port [port!] /seek number [integer!] ] [ Get-RIF port number ] write: func [port [port!] record [binary!]] [ Append-RIF port record ] ] ] |
Steeve 13-Aug-2010 [2208] | arghh... not here ;-) |
Andreas 13-Aug-2010 [2209x3] | There are action!s in R3, which operate in port!s. |
If you define custom schemes, you can implement how those actions behave for ports using your scheme by writing what we call "actors". | |
This is the elementary principle to understand. | |
Pavel 13-Aug-2010 [2212x2] | It is elementary dear Watson :-) |
Watson <- me here | |
Graham 13-Aug-2010 [2214] | http://www.rebol.net/wiki/Schemes:Notes#Actors |
Steeve 13-Aug-2010 [2215x2] | try to open the port at first and then call your read function with it |
when you directly use read on a path, i'm not sure that your 'open function is called | |
Andreas 13-Aug-2010 [2217] | Ah, all documented in the wiki :) |
Pavel 13-Aug-2010 [2218] | OK lets try it better, thanks guys for lesson learned! |
Andreas 13-Aug-2010 [2219x2] | (Refresh, if you have the page open. I just fixed the formatting.) |
But I think I'll refine the example and add an open? actor as well. | |
Pavel 13-Aug-2010 [2221] | I made it read: func [port [port!] /seek number [integer!] ] [ either empty? port/locals [ open port return Get-RIF port number ][ return Get-RIF port number ] and it works now |
Steeve 13-Aug-2010 [2222] | Btw Pavel, in my virtual-block scheme, the reason why I rebound the actors, is that I don't like to use nasty long path to acces my locals. |
Pavel 13-Aug-2010 [2223x2] | I hope close is in garbage collector as mentioned in wiki |
And second is more speed? | |
Steeve 13-Aug-2010 [2225] | It should be :-) |
Graham 13-Aug-2010 [2226] | can't you return get-rif either empty? ... |
older newer | first last |