How to Import modules without an Xcode project in Swift - swift

I am using the command line to create swift files and using the "swift" command in order to run one of them. However I would like one file to be able to access functions from another file. If this were C then I could use the #include macro and specify where the file is. But Swift's import statement doesn't seem to allow that. There should be a way and I would like to know how to do it.
for example:
If I have a file with a function in it and then I make another file that uses that function. How do I allow it to use it?
// file1.swift
import Foundation
func sayHello() -> String {
return "hello"
}
// file2.swift
import file1 // <-- trying to import file1 but it doesn't work
println(sayHello())
Once the files have been made I then write "swift file2.swift" in terminal. But it tells me..
error: no such module 'file1.swift'
clearly the swift compiler is looking for a module. How do I make file1 into a module? I've seen some solutions but they all take place in Xcode. What I'm looking for is to do it all in the command line.

// file1.swift
func sayHello() -> String {
return "hello"
}
// main.swift
println(sayHello())
and then from the terminal:
$ swiftc file1.swift main.swift
$ ./main
hello

See http://computers.tutsplus.com/tutorials/alfred-workflows-in-swift--cms-21807 for an example of creating a module (an Alfred helper library) from the command line, also http://www.alfredforum.com/topic/4902-alfred-workflows-in-swift-tutorial-is-available/?p=35662 where the author of the tutorial explains the four step compilation process in more detail.

Related

Preprocessor doesn't work for removing code from top level

I need to have a file input that can be executed as both - main for output, and a module for unit testing(because apparently you can't run tests again main.swift).
Let's say I have a file like this:
class Hello {}
#if RELEASE
print("hello")
#endif
Now, the idea here is that I can put this input into either a main.swift or something.swift and use a flag to remove the print("hello") when not in main.swift.
But it seems that no matter what I still get the error:
error: expressions are not allowed at the top level print("hello")
Is it possible to achieve what I want with the flags, or there's something weird going?

How to load multiple modules implementing the same behaviour

I do not understand how is one supposed to use multiple modules that each implement the same behaviour since i get this error at compile time:
Function is already imported from
In my case i have two modules implementing gen_event behaviour and i am trying to import them in a third module.
I get the error message whenever i am trying to compile this code:
-module(mgr).
-import(h1,[init/1]). // implements gen_event
-import(h2,[init/1]). // implements gen_event
You can't do that. Import is a simple trick to avoid to write the complete "definition" of a function. It does nothing but just says to the compiler : when you see init(P) in this module, replace with h1:init(P).
Thus it is not possible to import several function with the same name/arity.
For short names, I do not see any benefit to use import.
If you are using module:function with long names, and you want to shorten the lines in the code, it is possible to use macros instead, and there are no limitation (but also few chance that the function name are the same :o):
-define(Func1(Var1,...,VarN), module1:func(Var1,...,VarN)).
-define(Func2(Var1,...,VarN), module2:func(Var1,...,VarN)).
...
?Func1(A1,...,AN);
...
?Func2(B1,...,BN);
Edit
The next example illustrates how it works, first I create the module mod1 as follow:
-module (mod1).
-export ([test/1]).
test(P) ->
case P of
1 -> ok;
2 -> mod2:test()
end.
and I test it in the shell:
1> c(mod1).
{ok,mod1}
2> mod1:test(1).
ok
3> mod1:test(2).
** exception error: undefined function mod2:test/0
4> % this call failed because mod2 was not defined.
4> % lets define it and compile.
mod2 is created as:
-module (mod2).
-export ([test/0]).
test() ->
io:format("now it works~n").
continue in the shell:
4> c(mod2).
{ok,mod2}
5> mod1:test(1).
ok
6> mod1:test(2).
now it works
ok
7>
As you can see, it is not necessary to modify mod1, but only to create and compile mod2 (note that it would be the same if mod2 already exists but the function test/0 is not exported).
If you want to verify that your code is not using undefined function, you can use external tools. As I am using rebar3 to manage my projects, I use the command rebar3 xref to perform this check. Note that calling an undefined function is a simple warning, it is meaningful in the context of application upgrading. This verification is not bullet proof: it is done at build time, this does not guarantee that the modules yo need will be present, with the right version on a production system: it opens a lot more interesting questions about versioning, code loading...

Swift specific imports still import the entire module?

Ran into some interesting behavior in the Swift REPL:
1> import var Glibc.M_PI
2> M_PI
$R0: Double = 3.1415926535897931
3> M_E
$R1: Double = 2.7182818284590451
4>
According to the language documentation, only the symbol M_PI should be available when I do this import!
Import Declaration
An import declaration lets you access symbols that are declared outside the current file. The basic form imports the entire module; it consists of the import keyword followed by a module name:
import module
Providing more detail limits which symbols are imported—you can specify a specific submodule or a specific declaration within a module or submodule. When this detailed form is used, only the imported symbol (and not the module that declares it) is made available in the current scope.
import [import kind] [module].[symbol name]
import [module].[submodule]
But instead, M_E, sqrt(), sin(), log(), and the kitchen sink are now running around in the scope. How do I prevent all those other symbols from getting imported?
Strangely, this only happens in the Swift console; compiled Swift code doesn’t do this.

Inheriting command a file lib argparser

Good afternoon
I wonder how I can inherit commands from a file that created the commands using the lib argparser.
To make it easy to understand, I will put examples:
File 1: (The house of the project may not have anything useless)
import file2
code here
File 2: (containing the argparser values)
import argparse
class file2():
def function():
argumentos = argparse.ArgumentParser(description = 'My Program')
argumentos.add_argument('-command')
argumentos_recebe = argumentos.parse_args()
I would like to invez to call the file 2 I called the file using one of two commands.
example:
arquivo1.py -command
Instead of ..
arquivo2.py -command
I think this is possible using class most like to find out how!
When you import file1 from file1.py, you can then refer to its contents as attributes on the file1 module object. So, your file1 code can be something like:
import file2
object = file2.file2() # create an instance of the class
object.function() # call the function to parse the arguments
Now, this won't quite work as written with the file2 contents you showed, because your function method doesn't take a self argument. You may not actually need a class (unlike Java, you don't need to pack all of your functions into classes all the time in Python). If that's the case, you can move function to the top level of the module and drop the object parts of the my code. Then just call file2.function() and it will do the parsing. Note that you might want to return something from the function that's doing the parsing, if you need to access the results in the rest of your code in file1.

How do packages work in golang

I was trying to understand how packages work in go better in terms of what golang actually enforces rather than what is usually done or considered good practice (we can talk about good practice later too, but I wish to understand go first).
From effective go it says:
"Another convention is that the package name is the base name of its source directory..."
However, the description above doesn't seem to be forced by go or required. Thus, I was wondering, if I was allowed to have multiple files with different package declarations at the top in the same directory base. If I am allowed to have multiple package declaration in the same directory, how do I then import them and use each one separately in the same file? Basically, I guess one of the problem I have is due to the wording of some of the go tutorial/documentation. If it is by convention, then for me, its implied that it is NOT enforced by the language. Because for example, go programmers do NOT write the keyword func for a function by convention. We write func because otherwise go will yell at you and it will not compile. Thus, I wish to clarify this with the example bellow (and if possible change the documentation for go, because this is a big deal in my opinion, how can this be done?).
For example say I have three file A.go, B.go, C.go that print a print function Print() that simply prints a,b,c respectively. They are all on the same base directory called maybe base. Then each has a different package declaration package Apkg, package Bpkg, package Cpkg.
how would you then go and import them? Would something as follow work?
package main
import(
nameA "github.com/user_me/base/Apkg"
nameB "github.com/user_me/base/Bpkg"
nameC "github.com/user_me/base/Cpkg"
)
func main() {
nameA.Print() \\prints a
nameB.Print() \\prints b
nameC.Print() \\prints c
}
or maybe we don't even need to specify the name if the package statments are the top are already different:
package main
import(
"github.com/user_me/base"
)
func main() {
Apkg.Print() \\prints a
Bpkg.Print() \\prints b
Cpkg.Print() \\prints c
}
the printing file are:
A.go:
//file at github.com.user_me/base and name A.go
package Apkg
import "fmt"
func Print(){
fmt.Println("A")
}
B.go:
//file at github.com.user_me/base and name B.go
package Bpkg
import "fmt"
func Print(){
fmt.Println("B")
}
C.go:
//file at github.com.user_me/base and name C.go
package Cpkg
import "fmt"
func Print(){
fmt.Println("C")
}
Also, if you can have a name different from the base, could someone clarify to me how the import is actually done? If the package name is package Apkg in base does the import have to be import github.com/user_me/base or import github.com/user_me/base/Apkg or github.com/user_me/Apkg.
I have not yet tested this but I will do so soon. The importing deal in go has been a little confusing for me and would love to get an answer and share it with the world.
No, it's 1 package per folder, so you would have to have them :
$GOPATH/src/github.com/user_me/base/Apkg/a.go
$GOPATH/src/github.com/user_me/base/Bpkg/b.go
$GOPATH/src/github.com/user_me/base/Cpkg/c.go
You can't even build it otherwise:
┌─ oneofone#Oa [/t/blah]
└──➜ go build
can't load package: package .: found packages pkgA (blah1.go) and pkgB (blah2.go) in /tmp/blah
Your your package name doesn't need to have the same name as the directory they are in, however all files in one directory must have the same package name.
Also, you can rename packages on import, for example:
import (
cr "crypto/rand"
mr "math/rand"
)
Or your library is called main (bad idea btw) :
import m "github.com/user_me/base/main"