pragma.enable("easy-return") pragma.disable("explicit-result-guard") def makeBrand implements DeepFrozen { to run(label :String) :any { # This holds nullOk[Tuple[any]], but stating so now creates a # circular dependency makeBrand->nullOk->DeepFrozen, and is not # necessary since all the assignments maintain that condition. var unsealHolder := null def brand { to __printOn(out :TextWriter) :void { out.print(label) } } def sealer { to __printOn(out :TextWriter) :void { out.print("<", brand, " sealer>") } # XXX optSealedDispatch uncall /** Return the Brand of this sealer/unsealer set. */ to getBrand() :any { return brand } to seal(content) { def sealedBox { to __printOn(out :TextWriter) :void { out.print("") } # XXX optSealedDispatch uncall /** Return the Brand of the Unsealer which can unseal this * box. */ to getBrand() :any { return brand } /** An implementation detail. */ to _offerContent() :void { unsealHolder := [content] } } return sealedBox } } def unsealer { to __printOn(out :TextWriter) :void { out.print("<", brand, " unsealer>") } # XXX optSealedDispatch uncall /** Return the Brand of this sealer/unsealer set. */ to getBrand() :any { return brand } /** .unseal(specimen, null) */ to unseal(specimen) :any { return unsealer.unseal(specimen, null) } # The implementation structure is partially described in the # documentation here since it affects how the unsealer behaves # when given an object which pretends to be our sealed box. /** Unseal a SealedBox: return its contents. * * Call specimen._offerContent(), then return the contents of the * sealed box (of our brand), if any, whose _offerContent/0 * method is invoked last during the call. * * Note that an object which successfully unseals will not * necessarily give the same contents on a second unsealing. */ to unseal(specimen, optEjector) :any { try { unsealHolder := null if (specimen.__respondsTo("_offerContent", 0) \ && (specimen._offerContent(); unsealHolder =~ [content])) { return content } else { # XXX exception type # XXX distinguish not-a-box from not-our-box from # pretending-to-be-our-box? throw.eject(optEjector, `$specimen is not a $brand sealed box`) } } finally { unsealHolder := null } } } def brandKit { to __printOn(out :TextWriter) :void { out.print("<", brand, " brand kit>") } # XXX optUncall # XXX add list-imitating get/1 # XXX no tests for getSealer, getUnsealer to getSealer() :any { return sealer } to getUnsealer() :any { return unsealer } /** Return the Brand of this sealer/unsealer set. */ to getBrand() :any { return brand } /** This brand kit will coerce to a tuple, so that it may be * matched against a list pattern like * epatt`[sealer, unsealer]`. */ to __conformTo(guard) :any { switch (guard) { match == { return [sealer, unsealer] } match _ { return brandKit } }} } return brandKit } }