[e-lang] simple Guard example
Kevin Reid
kpreid at mac.com
Mon Jan 8 13:04:15 CST 2007
On Jan 8, 2007, at 8:46, Martin Scheffler wrote:
> I tried to create a simple example of how to create guards.
> The guard is supposed to guard objects created by a specific maker.
>
> It basically checks if the guarded object posesses a sealer that fits
> to the unsealer of the guard.
>
> Could you take a look at this? If this code is correct
It is not. I have explained the problems inline below.
> (and there is not a much simpler version of how to do it)
There is a much simpler version:
interface Certified implements CertifiedStamp {}
def certified implements CertifiedStamp { ... }
certified will pass the Certified guard.
Another way is to use sealed boxes containing the certified objects:
def certified {
to getBoxed() { return sealer.seal(certified) }
}
def Certified {
to coerce(specimen, ejector) {
def result := try {
unsealer.unseal(specimen.getBoxed())
} catch problem {
throw.eject(ejector, problem)
}
require(result == specimen) # optional
return result
}
}
If the result == specimen check is omitted, then the guard may return
a different object than it was provided, but it will still
necessarily be a certified object, since only certified objects will
be put into boxes.
> #------------------------->8----------------------------------------
>
> def makeBrandPair := <elib:sealing.makeBrand>
> # value: <makeBrand>
>
> def makeCertifiedMaker() :any{
>
> #create a sealer/unsealer pair
> def [certifiedSealer, certifiedUnsealer] := makeBrandPair
> ("certified")
The name should be supplied as a parameter, so that all instances can
have attempted distinct labels, or the name becomes worthless.
> def certifiedMaker {
>
> #This guard throws an error if an uncertified object is
> encountered
It does not throw, it ejects, as it should.
> to getGuard() :any {
> def CertifiedGuard {
This name would conventionally be a guard for certified guards.
Instead write:
def Certified {
> to coerce( specimen, ejector ) :any{
>
> def someObj := {}
This binds someObj to null. You probably meant
def someObj {}
> def sealed := specimen.seal
> ( someObj )
This mechanism can be defeated by a simple forwarder. It provides
only verification that the specimen *can invoke* the sealer with an
arbitrary argument, and the certified objects provide that authority.
> try {
>
> certifiedUnsealer.unseal( sealed )
In fact, since the contents of the sealed box are not checked, it can
be any sealed box that the specimen already had, not just a fresh one.
> } catch error {
> throw.eject( ejector,
> "This is not a certified object!" )
> return null
This return will never be reached and should not be present,
especially as null is an uncertified object.
> }
> return specimen
> }
> }
> return CertifiedGuard
> }
>
> to run() :any {
> def certified{
> to print() :void{println("I am a
> certified object!")}
> to seal(obj) :any {return
> certifiedSealer.seal(obj)}
By providing this method, the certified object provides the authority
to create arbitrary sealed boxes.
> }
> return certified
> }
> }
> return certifiedMaker
> }
> # value: <makeCertifiedMaker>
>
> def certifiedMaker:=makeCertifiedMaker()
> # value: <certifiedMaker>
>
> def Certified:=certifiedMaker.getGuard()
> # value: <CertifiedGuard>
>
> def myCertified:=certifiedMaker()
> # value: <certified>
>
> def test :Certified :=myCertified
> # value: <certified>
>
> test.print()
> #stdout: I am a certified object!
>
> def [fakeSealer, fakeUnsealer] := makeBrandPair("certified")
> # value: [<certified sealer>, <certified unsealer>]
>
> def fakeCertified{
>
> to print() :void{
> println("HAHA, i sneaked in!")
> }
>
> to seal(obj) :any {
> return fakeSealer.seal(obj)
fakeCertified can simply do e`return myCertified.seal(obj)` here in
order to pass the guard. Of course, this requires that it have access
to some other certified object, but that is a common case.
> }
> }
> # value: <fakeCertified>
>
> def test2 :Certified :=fakeCertified
> # problem: This is not a certified object!
> #
> # - Thrower#eject(OneArgFunc, RuntimeException)
> # (...)
>
> #------------------------->8-----------------
--
Kevin Reid <http://homepage.mac.com/kpreid/>
More information about the e-lang
mailing list