Walnut/Advanced Topics
From Erights
Contents |
Advanced Topics
Some of the items in this potpourri of topics are not difficult to understand or use, they are simply used less often than the main features of the language.
MenuMaker
E Properties File
E installations include the props.txt properties file, chock full of information that is occasionally useful. You can access it through the interp object. In this example, we get the home directory for the E installation, which can be useful if you wish to store data in a known location to be shared by multiple E programs:
pragma.syntax("0.9") def ehomePath := (interp.getProps()) ["e.home"]
The properties are stored in a map which can be accessed in the usual manner. For a complete listing of the information in the props.txt file, open yours up and take a look.
Build your Own uriGetter
So you think it would be cool to access your own data using the syntax of the style <getter:description>. No sweat: just implement an object with the single method get(description), and assign it to a variable with the name xxx__uriGetter:
# E sample def myDir := <file:/home/usr/me/myDir> def myDir__uriGetter { to get(objectPath) { return myDir[objectPath] } } def myFile := <myDir:theFileOfMyDreams.txt>
EAction and the trouble with listener callbacks
the entropy random number generator
Instead of using
def x := blah; if (blah != null) {...},
instead use
if (blah =~ x:notNull) {...}
for java calls to objects using deflectors on eventlistener interfaces, the calls are converted into sends
having multiple constructors and inheritance at the same time
Rights amplification
how to wait on a device like a socket
building your own quasiparsers
weak pointers
operators for twine like split and rjoin
twine versus string, run versus substring, etc.
Note that the revoker system presented earlier only works if the facetized object and the revokable user are not collaborating; if they are collaborating, use membranes.
S-expression/XML quasi-parser
Build Your Own Guards
# E template
def simple_guard { to coerce(specimen, optEjector) :near { if (specimen fits criteria) { return specimen } else { throw.eject(optEjector, "Specimen didnt fit criteria") } } }
First, here is a simple guard that matches integer strings and converts them to integers:
def asInt { to coerce(specimen, optEjector) :int { try { return __makeInt(specimen :String) } catch ex { throw.eject(optEjector, ex) } } }
You can use it like this:
def str := "5 + 7 = 12" def `@{a:asInt} + @{b:asInt} = @{c:asInt}` := str require(a + b == c)
Now for a more complicated example...
Here is the emaker that makes a pair of VOC claim check guards, a proveAuth (i.e., a claimCheck), and a checkAuth (i.e., a checkedClaim):
# E sample
def makeVOCPair(brandName :String) :near { var myTempContents := def none {} def brand { to __printOn(out :TextWriter) :void { out.print(brandName) } } def ProveAuth { to __printOn(out :TextWriter) :void { out.print(`<$brandName prover>`) } to getBrand() :near { return brand } to coerce(specimen, optEjector) :near { def sealedBox { to getBrand() :near { return brand } to offerContent() :void { myTempContents := specimen } } return sealedBox } } def CheckAuth { to __printOn(out :TextWriter) :void { out.print(`<$brandName checker template>`) } to getBrand() :near { return brand } match [`get`, authList :any[]] { def checker { to __printOn(out :TextWriter) :void { out.print(`<$brandName checker>`) } to getBrand() :near { return brand } to coerce(specimenBox, optEjector) :any { myTempContents := null if (specimenBox.__respondsTo("offerContent", 0)) { # XXX Using __respondsTo/2 here is a kludge specimenBox.offerContent() } else { myTempContents := specimenBox } for auth in authList { if (auth == myTempContents) { return auth } } myTempContents := none throw.eject(optEjector, `Unmatched $brandName authorization`) } } } match [`__respondsTo`, [`get`, _]] { true } match [`__respondsTo`, [_, _]] { false } match [`__getAllegedType`, []] { null.__getAllegedType() } } return [ProveAuth, CheckAuth] }
Now here is an example of the pair of VOC guards in use:
? def [ProveAuth, CheckAuth] := <elib:sealing.makeVOCPair>("voc") # value: [<voc prover>, <voc checker template>] ? def f1 := <file:~/.bashrc> # value: <file:c:/Documents and Settings/millerm1/.bashrc> ? def f2 := <file:~/Desktop> # value: <file:c:/Documents and Settings/millerm1/Desktop/> ? def foo(f :CheckAuth[f1,f2]) :void { > println(f.getPath()) > } # value: <foo> ? foo(f1) # stdout: c:/Documents and Settings/millerm1/.bashrc # ? def f3 := <file:~> # value: <file:c:/Documents and Settings/millerm1/> ? foo(f3) # problem: Unmatched voc authorization ? foo(f1 :ProveAuth) # stdout: c:/Documents and Settings/millerm1/.bashrc # ? foo(f3 :ProveAuth) # problem: Unmatched voc authorization ? def bar(f) :void { > println(f.getPath()) > } # value: <bar> ? bar(f1) # stdout: c:/Documents and Settings/millerm1/.bashrc # ? bar(f1 :ProveAuth) # problem: <NoSuchMethodException: <a sealedBox>.getPath/0>
Next Section: Appendix