#709 Working with multiple source files

efficacy Fri 7 Aug 2009

I'm relatively new to fan, but so far I have been unable to find an answer to what seems a simple question. It's very likely I'm missing something obvious, but it feels as if it should be something in the introductory documents.

How do I work with multiple source files?

For example:

file 1 (hello.fan)

class HelloWorld {
  static Void main() {
    Component().thing
  }
}

file 2 (thing.fan)

class Component {
  Void thing() {
    echo("I am a thing")
  }
}

If I put the contents of thing.fan inside hello.fan it all works fine, but when they are in separate files I get

hello.fan(3,5): Unknown method hello_0::HelloWorld.Component

On the surface it looks like "using" is the solution to this, but the examples are very light on "using", and from what I can find it seems I would need to specify a "pod". But my code is not in a "pod"!

I can't find any syntax to specify the name of a file to use, either. Is there any such thing? How do more experienced fan programmers work with multiple source files?

Although we may rail against the fuss of enforced source file names in Java, at least they provide a way round this problem for the Java compiler :|

andy Fri 7 Aug 2009

Looks like you're running Fan as scripts. You can't import other script files right now when running Fan this way. You will need to create a full pod if you intend to split your code up in multiple files. See here and here for info on running scripts and buildling pods.

Unlike Java, there are no rules with file names (class and filename do not have to match), and you can include multiple types in a single source file.

brian Fri 7 Aug 2009

most of the focus has been on Fan's module system, so using doesn't let you import script files

although you can use sys::Sys.compile to compile external files into pods (but they won't be brought into the static namespace)

efficacy Sat 8 Aug 2009

Thanks.

That's not the answer I was hoping for, but I'll press on.

I obviously missed something major in the examples, as I assumed that fan was primarily a compile-on-demand script language like python or ruby, with the "pod" mechanism for advanced uses such as bundling up code and resources for deployment to a different machine.

I think I may have come to this conclusion because all the examples seem to be single scripts. So far I have not found any tutorial example which walks a user through everything needed to build and run a more realistic-sized application. Perhaps this is something which could be added to the documentation?

I looked at the build page and followed its instructions. I created a dir "fantest" with a subdir "src", put the two files from my initial question into "src" and created a file "build.fan". My project structure now looks like:

fantest/
  build.fan
  src/
    hello.fan
    thing.fan

My "build.fan" looks like

using build

class Build : BuildPod
{
  override Void setup()
  {
    podName     = "fantest"
    version     = globalVersion
    description = "A test of Fan"
    depends     = ["sys 1.0+"]
    srcDirs     = [`src/`]
  }
}

As far as I can tell this is a reasonable interpretation of the instructions.

However, when I run "fan build" all I get is

build it!

and nothing seems to be created.

Have I missed something? Is it creating some executable pod object somewhere else?

KevinKelley Sat 8 Aug 2009

That build page is about extending the build system. What it had you do was, create a new build-target that just prints a message.

This is the quick intro to compiling Hello World in pod form.

brian Sat 8 Aug 2009

I obviously missed something major in the examples, as I assumed that fan was primarily a compile-on-demand script language like python or ruby, with the "pod" mechanism for advanced uses such as bundling up code and resources for deployment to a different machine.

I would say Fan is squarely a statically compiled language with built-in modules - that is definitely its key focus. But scripting is really nice too.

If there is support for allowing URIs to import external scripts that is certainly something we could look at (gets kind of tricky with Fan's pod/type/slot namespace though).

I looked at the build page and followed its instructions.

I apologize that those docs are out of date, I forget to update them for the last build to align with the latest changes.

As Kevin pointed out, a correct example is for hello world

efficacy Sat 8 Aug 2009

Thanks guys, that did it.

I now have a working (albeit trivial) "pod".

I was a little surprised that the default behaviour is to hide my random application code in with the supplied pods that come with the compiler. I can see that it makes path lookups easier, but it could become a nightmare as people work on multiple projects, and even multiple versions of the same code. I long ago gave up putting anything on the system classpath in Java, for example.

Most compilers which I have encountered place the generated object or executable files in the current directory - is there a way to work like this with fan?

brian Sat 8 Aug 2009

I was a little surprised that the default behaviour is to hide my random application code in with the supplied pods that come with the compiler.

This is a brand new feature (so it has some rough edges). But you can create a working repo for your code, to keep it separate from the distro pods. See docLang::Repos.

brian Sun 9 Aug 2009

I have updated the online docs for docTools to reflect the new symbol design (and pushed the fixes to hg).

I apologize for leaving those docs out of date - not my style, but I was a bit overwhelmed by that last batch of changes.

Login or Signup to reply.