Walnut/Advanced Topics

From Erights

Jump to: navigation, search


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

Personal tools
more tools