Hi all,
I've been experimenting with the NetRexx interpreter API and came across some surprising behaviour when dealing with static state. For starters, consider the following code which increments a static field: --( counter.nrx )--------------------------------- class counter properties static n = 0 method increment static n = n + 1 return n -------------------------------------------------- and a simple client to call the increment method, --( client.nrx )---------------------------------- say "(in client.nrx)" say "=>" counter.increment -------------------------------------------------- Running 'client.nrx' yields the expected result, --8<---------------------------------------------- $ nrc -run client counter NetRexx portable processor, version NetRexx 3.01RC2, build 1-20110925-2337 Copyright (c) RexxLA, 2011. All rights reserved. Parts Copyright (c) IBM Corporation, 1995,2008. Program client.nrx Program counter.nrx === class counter === function increment Compilation of 'client.nrx' successful Compilation of 'counter.nrx' successful Running client... (in client.nrx) => 1 --8<---------------------------------------------- So far, so good. Now for the interpreter. This code parses/interprets 'client.nrx' and calls the its main (static) method: --( interpreted.nrx )---------------------------------- import org.netrexx.process. interp1 = NetRexxA() interp2 = NetRexxA() -- Increment twice to make things clear: counter.increment say "~ interpreted.nrx counter:" counter.increment rule = '-'.copies(40) say rule loop for 3 say ":: performParse [interp1]" performParse(interp1) say ":: performInterpret [interp2]" performInterpret(interp2) say rule end method performParse(interpreter=NetRexxA) static files = [String 'client.nrx'] flags = [String 'nologo'] res = 0 do res = interpreter.parse(files, flags) if \res then return c = interpreter.getClassObject(null, "client") if c = null then do say "Class 'client' not found." return end m = c.getMethod("main", [flags.getClass]) m.invoke(c, [Object files]) catch ex=Exception ex.printStackTrace end return method performInterpret(interpreter=NetRexxA) static do output = slurp("client.nrx") interpreter.interpret("client", output, "", "") catch ex=Exception ex.printStackTrace end return method slurp(filename) static- signals FileNotFoundException, IOException reader = BufferedReader(FileReader(filename)) line = reader.readLine output = '' loop while line <> null output = output'\n'line line = reader.readLine end return output ------------------------------------------------------- First, 'interpreted.nrx' increments the counter twice and prints the second result (this is just to make things clearer). It then loops three times calling (a) 'parse' and (b) 'interpret' on distinct NetRexxA instances. Reuse of 'files' and 'flags' for method invocation is just to keep things concise. Here's the output: --8<---------------------------------------------- $ nrc -run interpreted NetRexx portable processor, version NetRexx 3.01RC2, build 1-20110925-2337 Copyright (c) RexxLA, 2011. All rights reserved. Parts Copyright (c) IBM Corporation, 1995,2008. Program interpreted.nrx function performParse(NetRexxA) function performInterpret(NetRexxA) function slurp(Rexx) Compilation of 'interpreted.nrx' successful Running interpreted... ~ interpreted.nrx counter: 2 ---------------------------------------- :: performParse [interp1] Program client.nrx (in client.nrx) => 1 :: performInterpret [interp2] (in client.nrx) => 1 ---------------------------------------- :: performParse [interp1] Program client.nrx (in client.nrx) => 1 :: performInterpret [interp2] (in client.nrx) => 2 ---------------------------------------- :: performParse [interp1] Program client.nrx (in client.nrx) => 1 :: performInterpret [interp2] (in client.nrx) => 3 ---------------------------------------- --8<---------------------------------------------- Two things surprised me here: [1] Both 'performParse' and 'performInterpret' start with a counter state of 0, not 2 -- mutation performed by 'interpreted.nrx' prior to calling these methods has no effect. [2] The 'interpret' method maintains state between calls while 'parse' does not (perhaps because 'interpret' calls 'exec' on the translator while I explicitly call getClassObject after 'parse'.) I'd appreciate it if someone could explain this -- both the lack of shared state between host and interpreter and the different behaviour of 'interpret' and 'parse'. Finally: is there a (safe) way to share static state between 'interpreted.nrx' and a NetRexxA instance? Best, M _______________________________________________ Ibm-netrexx mailing list [hidden email] Online Archive : http://ibm-netrexx.215625.n3.nabble.com/ |
Free forum by Nabble | Edit this page |