Scripts/WS Files
An APL workspace is a collection of names available in the runtime environment, which can be saved into a file that is also called a workspace. The memory workspace roughly corresponds to J locale, however in J there is no standard facilities to store locales in files, except for redefining the names from text.
This script provides succinct facilities for persisting J locale names in binary files in a way close to how APL commands )SAVE, )LOAD, )COPY and )LIB work.
Features
- select names by mask, type (0 1 2 3) using nl convention or verbatim list
- wsload and wssave work with selective names, providing "copy" functionality
- wsnl lists contents of workspace, filter parameters show the same names as for wsload
- protect flag prevents overwriting of existing names in file or locale
- works in current locale, specify locale _suffix_ to override, eg wssave_j_'' saves locale j
- uses keyfiles as storage backend
- stores extra info: name class and size
- nouns are saved using binary represenation 3!:1
- non-nouns are stored using atomic representation 5!:1
- affected names are returned in boxed list with "-" prefix for protected names
Applications
- ad-hoc storage for J locales
- save-restore functionality for postponed calculations, such as saved session between stateless requests in HTTP server etc.
Script
The script is based on original File:Ws orig.ijs by Eke van Batenburg posted Mar 24 1997 to comp.lang.apl.
NB. wsfiles - workspace files in J NB. works in current locale, specify _suffix_ to override NB. 04/18/08 Oleg Kobchneko - extended j60x version NB. 03/24/97 Eke van Batenburg - initial prototype NB. http://groups.google.com/group/comp.lang.apl/msg/861e2f6641b5905e require 'files jfiles' coclass 'z' WSEXT=: '.jws'
Public interface
wssave v save names (of types) x to file y
wsload v load names (of types) x from file y
wsnl v list names (of types) x in file y
NB.*wssave v save names (of types) x to file y NB. y filename[;protect] NB. filename with optional extension, .jws default NB. protect names: 0 or 1 (1 default) NB. x names pattern or types 0 1 2 3, all default NB. eg 0 3 wssave 'work' NB. '*bc' wssave_z_ 'work';0 NB. ('a';'bc') wssave 'work';0 wssave=: 3 : 0 '' wssave y : 'fileName prot'=. 2{.(boxopen y),<1 if. -.fexist fileName=. wsfile fileName do. keycreate fileName end. dir=. nl'' if. 0=#x do. names=. dir elseif. 32=3!:0 x do. names=. x #~ x e. dir elseif. 2=3!:0 x do. names=. x nl '' elseif. 1 do. names=. nl x end. z=. '' for_name. names do. if. prot do.if. -. _4-:keyread fileName,name do. z=. z,'-',&.>name continue. end. end. z=. z,name cls=. nc <fullName=. cofullname name if. 0 > cls do. continue. end. if. 0 = cls do. value=. <fullName~ else. value=. 5!:1 <fullName end. value keywrite fileName,name extra=. <cls;(#@(3!:1) value) extra keywritex fileName,name end. z ) NB.*wsload v load names (of types) x from file y NB. y filename[;protect] NB. x names pattern or types 0 1 2 3, all default NB. eg 0 3 wsload 'work' NB. 'bc' wsload 'work';0 NB. ('a';'bc') wsload 'work' wsload=: 3 : 0 '' wsload y : 'fileName prot'=. 2{.(boxopen y),<1 fileName=. wsfile fileName names=. x wsnames fileName z=. '' for_name. names do. fullName=. cofullname name if. prot do.if. _1 < nc<fullName do. z=. z,'-',&.>name continue. end. end. z=. z,name cls=. >@{.&> keyreadx fileName,name value=. keyread fileName,name if. 0 = cls do. (fullName)=: >value else. (fullName)=: value 5!:0 end. end. z ) NB.*wsnl v list names (of types) x in file y NB. y filename with optional extension (.jws default) NB. x names pattern or types 0 1 2 3, all default NB. eg 0 3 wsnl 'work' NB. '~bc' wsnl 'work' NB. wsnl 'work' wsnl=: 3 : 0 '' wsnl y : fileName=. wsfile >y if. #names=. x wsnames fileName do. extra=. >keyreadx fileName,<names (;:'name nc size'), names ,. extra else.''end. )
Private helper verbs
Not intended to be used externally.
NB. ========================================================= wsnames=: 4 : 0 ('File ',(>y),' not found') assert fexist y cls=. >@{.&> keyreadx y dir=. keydir y if. 0=#x do. names=. dir elseif. 32=3!:0 x do. names=. x #~ x e. dir elseif. 2=3!:0 x do. names=. dir #~ x wsmatch dir elseif. 1 do. names=. dir #~ cls e. x end. ) wsfile=: 3 : '< jpath ,&WSEXT^:([:-.''.''&e.) >y' wsmatch=: 4 : 0 if. 0=#y do. '' return. end. if. 0=#t=. x -. ' ' do. y return. end. 'n s'=. '~*' e. t t=. t -. '~*' b=. t&E. &> y if. s do. b=. +./"1 b else. b=. {."1 b end. n ~: b )
Testing of available functionality. Very helpful to maintain validity during code changes.
NB. ========================================================= Note 'Test' NB. select and Ctrl+E ferase jpath '~temp/test.jws' erase nl'' abctst=. 1 2 3 abetsz=. 1;2;3 abdtst=. + cd1tst=. / cd2tsz=. " assert 3-:# 'a'wssave '~temp/test' assert 0-:#(;:'a')wssave '~temp/test' assert 3-:#'*tst'wssave '~temp/test' assert 2-:# 0 wssave '~temp/test' assert 3-:# 0 1 wssave '~temp/test' assert '-'*./ . = {.&> 0 wssave '~temp/test' assert '-'*./ . ~: {.&> 0 wssave '~temp/test';0 ferase jpath '~temp/test.jws' wssave '~temp/test';0 erase nl'' wsnl '~temp/test' assert 4-:# 'a'wsnl '~temp/test' assert 0-:#(;:'a')wsnl '~temp/test' assert 4-:#'*tst'wsnl '~temp/test' assert 3-:# 0 wsnl '~temp/test' assert 4-:# 0 1 wsnl '~temp/test' wsload '~temp/test' assert abctst -: 1 2 3 assert abetsz -: 1;2;3 assert (5!:5<'abdtst') -: (,'+') assert (5!:5<'cd1tst') -: (,'/') assert (5!:5<'cd2tsz') -: (,'"') erase nl'' assert 2-:# 0 wsload '~temp/test' assert '-'*./ . = {.&> 0 wsload '~temp/test' assert '-'*./ . ~: {.&> 0 wsload '~temp/test';0 erase nl'' ferase jpath '~temp/test.jws' )