24

Having a file with function definition bar.swift:

func bar() {
    println("bar")
}

And a script to be run in immediate mode foo.swift:

#!/usr/bin/xcrun swift -i
bar()

How do you import bar.swift's bar() function from foo.swift?

Mirek Rusin
  • 18,820
  • 3
  • 43
  • 36

2 Answers2

30

I think the answer right now is that you can't split code across multiple files unless you compile the code. Executing with #!/usr/bin/swift is only possible for single file scripts.

It's obviously a good idea to file an enhancement request at http://bugreport.apple.com/, but in the mean time you're going to have to compile the code before executing it.

Also, your foo.swift file cannot have that name, you have to rename it to main.swift. If there are multiple files being complied, then only main.swift is allowed to have code at the top level.

So, you have these two files:

main.swift:

bar()

bar.swift:

func bar() {
    println("bar")
}

And compile/execute the code with:

$ swiftc main.swift bar.swift -o foobar

$ ./foobar 
bar

If all your swift files are in the same directory, you could shorten the compile command:

$ swiftc *.swift -o foobar

Or if you want to search child directories:

$ find . -iname '*.swift' | xargs swiftc -o foobar
Abhi Beckert
  • 32,787
  • 12
  • 83
  • 110
  • Thanks, works for me. For some reason I don't have `swiftc` installed, but all the above also applies to `xcrun swiftc`. – Thilo Dec 12 '14 at 08:58
  • @Thilo Make sure you have the latest version of Xcode from the App Store and, then after that run `xcode-select --install` in terminal. You should have `swiftc` after that. When I tried to use the code you're using I got a compile error saying that syntax is no-longer allowed. So you're clearly running an old version. – Abhi Beckert Dec 12 '14 at 10:52
0

Write a bash script to concatenate the files. The script below pre-pends the library file to the front of your script before execution:

#!/bin/bash

cat $HOME/my_swift/my_library_to_add.swift $1.swift > t.swift
swift t.swift

As the resulted file is the single use, you can place it on the RAM drive. Here is the more advanced version that creates or reuses the tiny 1 Mb RAM drive as required.

if [ ! -d /Volumes/swift_buffer ]; then
   diskutil erasevolume HFS+ 'swift_buffer' `hdiutil attach -nomount ram://2048`
fi

cat $HOME/my_swift/my_library_to_add.swift $1.swift > /Volumes/swift_buffer/t.swift   
swift /Volumes/swift_buffer/t.swift

This creates a tiny RAM drive with the capacity of 1 Mb only, big enough for any utility script and simple library.

The mounted RAM drive will be visible in the Finder, from where it can be ejected. I do not dispose it directly in the script as allocating takes time.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93