29. Naming
Overview
A "name" is a set of conventions and rules for using strings as identifiers. Good names are typically human readablealthough that isn't necessarily required. Fantom provides a unified naming design based on the Uri class. Uris are a good choice for naming because they provide:
- Ability to transcribe the name into an ASCII string (with appropriate escaping)
- Well defined model for plugging in "protocol" (scheme) handlers
- Well defined model for path hierarchies
- Well defined model for name/value pairs via queries
- Well defined rules for relativization and normalization
- Uris map cleanly to web based applications
- Uris are widely supported in alternate languages and platforms
Resolving Uris
In Fantom anything of interest we might wish to identify with a name is assigned a Uri. We resolve Uris to sys::Obj instances. The actual object type is dependent on the Uri. For example all "file:" Uris will resolve to a sys::File. Resolving a Uri is done via the Uri.get method:
File f := `file:/dir/file.txt`.get
If the file cannot be resolvedthen UnresolvedErr is thrown. You can pass false for the checked parameter to return null if the Uri cannot be resolved.
The default behavior of Uri.get on a relative Uri (null scheme) is to throw UnresolvedErr. But you can pass in optional base object. If the Uri is relativethen we attempt to resolve the base object's uri via the dynamic call base->uri. If the base's uri is absolutethen resolve we base->uri + uri:
base := `file:/dir/`.get `file.txt`.get(base) => resolves to `file:/dir/file.txt`
Uri Schemes
The UriScheme class is used to plug in handling for new Uri schemes. The standard fan runtime provides support for the following schemes:
- fan: resolves to the objects in the Fantom namespace (discussed below)
- file: resolves to
Fileinstances on the local file system - http: not done yetbut coming soon...
You can plug in your own scheme handling by subclassing UriScheme:
const class CustomScheme : UriScheme
{
override Obj? get(Uri uriObj? base) { ... }
}
You override the get method to implement uri to object resolution. To register your schemedefine an indexed prop formatted as:
sys.uriScheme.{scheme}={qname}
Where scheme is the lower case scheme name and qname is the qualified name of your scheme type. Indexed props are defined your build scriptfor example:
index = ["sys.uriScheme.fan": "sys::FanScheme"]
Fan Scheme
The Fantom runtime includes support for the "fan:" scheme which is used to identify objects related to the Fantom namespace:
fan://pod/dir/file.txt => sys:Pod.file (resource file)