#935 Env API

brian Tue 26 Jan 2010

This is adjunct to #867 to define a pluggable mechanism for customized bootstrap of Fantom.

Definition of a new sys::Env API:

const abstract class Env
{
   static Env cur()
   ...
}

Virtual instance methods on Env will completely replace static methods on Sys (which gets removed):

Sys.out   => Env.cur.out
Sys.in    => Env.cur.in
Sys.args  => Env.cur.args
Sys.exit  => Env.cur.exit
Sys.env   => Env.cur.vars

This will give developers flexibility to safely craft environments that handle std I/O or to trap things like exit.

We will also remove the Repo class and move key functionality into hooks on Env:

File homeDir()
File workDir()
File tempDir()

Plus all the hooks for resolving pods will be provided:

File? findFile(Uri, Bool)
File? findPodFile(Uri, Bool)

The initial system will bootstrap with a built-in BootEnv which only loads from fan.home.

Then maybe we create a simple util:PathEnv that will provide functionality to existing working/home repo design.

Eventually a VM could support multiple Envs, but for now I'd like to focus on a VM having exactly one Env (although you could easily build multiple Envs in Java if you loaded sys via different class loaders). The Env used will be configured with environment variable "FAN_ENV" similiar to how repos work today. The target Env class itself will be loaded from the boot environment (so it must be available in fan.home lib).

brian Tue 26 Jan 2010

Promoted to ticket #935 and assigned to brian

katox Tue 26 Jan 2010

Is it possible to leave Sys.in and Sys.out as convenience functions for Env.cur.*? Though one can use echo writing Env.cur.out.print in scripts looks overly verbose.

brian Tue 26 Jan 2010

Is it possible to leave Sys.in and Sys.out as convenience functions for Env.cur.*?

I don't think we should keep around the Sys class just to save four chars for a couple cases, especially since have echo as a convenience. Plus I like the idea of making it crystal clear that everything is being delegated to the configured environment class.

jodastephen Wed 27 Jan 2010

Do you intend to allow developers to change Env.cur to point to their own implementation? (In config or in code?)

brian Wed 27 Jan 2010

Do you intend to allow developers to change Env.cur to point to their own implementation? (In config or in code?)

Yes. For starters you can pass your Env class on either the command line or with the FAN_ENV environmental variable.

After some experience with the design we might want to allow spawning alternate environments within the same VM (like you might use ClassLoaders in Java).

And for those Java guys putting Fantom into J2EE containers this should make it easy to customize how each WAR gets booted up into its own Env.

Plus the OSGi guys can create a OsgiEnv.

jodastephen Thu 28 Jan 2010

I asked, because it feels like you really want Env to be a singleton, not a static. What I mean is that:

Env.out
Env.args

should not be invoking static methods on Env, but methods on the singleton object Env (which can be replaced). This way, you don't need the .cur part.

I raised something very similar in `http://fantom.org/sidewalk/topic/404`.

brian Thu 28 Jan 2010

Using Env.cur is definitely a little annoying, but still nowhere near as obnoxious as something like Java's Runtime.getRuntime. The problem is you need to define virtual methods, and it seems ugly to create a whole set of both static methods and virtual methods. Plus if you are implementing Env yourself you need to get access to instance methods.

So there has to be a class that has normal virtual methods. It is another question if we want to make it more convenient to use either with wrapper static methods or some language feature.

But honestly I didn't find these methods used all that often that I considered a real problem. I would suggest everybody play with the latest build and see how it strikes you.

brian Tue 2 Feb 2010

Ticket resolved in 1.0.50

This feature is complete for next build. The sys::Sys API has been removed, it is completely replaced by sys::Env. You can plug-in your own custom Env using the FAN_ENV environment variable which gives you hooks to customize:

  • args, env vars
  • std IO
  • home, work, temp directories
  • search path resolution
  • pod resolution
  • config property resolution
  • locale property resolution
  • Java classloading resolution

It is the single focal point for creating customized Fantom environments. The Env API is sort of like Java's ClassLoader API, but more comprehensive. The cool thing is that you can implement new Env classes in Fantom code.

The sys::Repo API has also been removed. It is replaced by util::PathEnv which takes a path of one or more directories via the FAN_ENV_PATH environment variable to provide the same functionality as FAN_REPO.

Using symbols for etc file configuration has been replaced by props files. All of the readSymbol and writeSymbol IO methods have been removed.

Note new locations for key configuration data:

lib/sys.props         =>  etc/sys/config.props
etc/build/pod.fansym  =>  etc/build/config.props

It is my hope that with these new APIs we'll see some cool new Env architectures for things like Jigsaw, OSGi, and cloud based repositories.

katox Tue 2 Feb 2010

That's really cool. Another positive thing is that a networked repository will check up things like pod versioning early.

tactics Tue 2 Feb 2010

Very cool. It should also help for Fantom as an embedded scripting language, if we ever evolve in that direction.

Login or Signup to reply.