Scripts/WS Files

From J Wiki
Jump to navigation Jump to search

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'
)

script: Wsfiles.ijs

See Also