All you need is docker (and fig)

IntroductionSuppose you want to run scala repl or groovy shell or any other repl-like executable. You should download executable, unpack it, set PATH environmnt variable and now you could use it. Can it be simple? Yes, dockerize everything.Prepare cont…

Introduction

Suppose you want to run scala repl or groovy shell or any other repl-like executable. You should download executable, unpack it, set PATH environmnt variable and now you could use it. Can it be simple? Yes, dockerize everything.

Prepare containers

I expect that you have installed docker and fig on your machine.
Checkout this project from github and build containers:
$ cd docker-with-fig
$ fig build 
It could take several minutes, depends on your internet connection.
You could also build only some of available container, for example with scala and groovy:
$ fig build scala groovy
Available containers are:
  • haskell
  • scala
  • groovy
  • python27
  • python34
  • clojure

Run containers

Now you could start for example scala:
$ fig run scala
Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions to have them evaluated.
Type :help for more information.

scala>
Or groovy:
$ fig run groovy
Mar 29, 2015 7:48:22 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Groovy Shell (2.4.2, JVM: 1.8.0_40)
Type ':help' or ':h' for help.
-------------------------------------------------------------------------------
groovy:000>
Or clojure with lein:
$ fig run clojure
nREPL server started on port 52730 on host 127.0.0.1 - nrepl://127.0.0.1:52730
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_40-b25
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=>
Or python 3.4:
$ fig run python34
Python 3.4.2 (default, Oct  8 2014, 13:08:17) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Or ghci haskell:
$fig run haskell
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>
You could also run command on docker container with use of files from your current directory because it is mapped to /project directory on docker. Container starts with /project directory as current directory.
For example you have a simple file in your current dir:
$ cat simplePrint.scala 

println("Hello World")


You could run command with this file:

$ fig -f PATH_TO_DOCKER_WITH_FIG_PROJECT/fig.yml run scala scala simplePrint.scala

Hello World

First ‘scala’ in command means that you want to run scala container and ‘scala simplePrint.scala’ means that you want to execute this command on container.

Conclusion

It is simple, isn’t it? All you need is docker and fig and you could use repl or run command with scala, groovy, cojure and any other which are currently supported…
You May Also Like

Use asInstanceOf[T] carefully!

BackgroundScala has nice static type checking engine but from time to time there are situations when we must downcast some general object. If this casting is not possible we expect that virtual machine will throw ClassCastExeption as fast as possible. ...

Private fields and methods are not private in groovy

I used to code in Java before I met groovy. Like most of you, groovy attracted me with many enhancements. This was to my surprise to discover that method visibility in groovy is handled different than Java!

Consider this example:

class Person {
private String name
public String surname

private Person() {}

private String signature() { "${name?.substring(0, 1)}. $surname" }

public String toString() { "I am $name $surname" }
}

How is this class interpreted with Java?

  1. Person has private constructor that cannot be accessed
  2. Field "name" is private and cannot be accessed
  3. Method signature() is private and cannot be accessed

Let's see how groovy interpretes Person:

public static void main(String[] args) {
def person = new Person() // constructor is private - compilation error in Java
println(person.toString())

person.@name = 'Mike' // access name field directly - compilation error in Java
println(person.toString())

person.name = 'John' // there is a setter generated by groovy
println(person.toString())

person.@surname = 'Foo' // access surname field directly
println(person.toString())

person.surname = 'Bar' // access auto-generated setter
println(person.toString())

println(person.signature()) // call private method - compilation error in Java
}

I was really astonished by its output:

I am null null
I am Mike null
I am John null
I am John Foo
I am John Bar
J. Bar

As you can see, groovy does not follow visibility directives at all! It treats them as non-existing. Code compiles and executes fine. It's contrary to Java. In Java this code has several errors, pointed out in comments.

I've searched a bit on this topic and it seems that this behaviour is known since version 1.1 and there is a bug report on that: http://jira.codehaus.org/browse/GROOVY-1875. It is not resolved even with groovy 2 release. As Tim Yates mentioned in this Stackoverflow question: "It's not clear if it is a bug or by design". Groovy treats visibility keywords as a hint for a programmer.

I need to keep that lesson in mind next time I want to make some field or method private!