Mirah Howto
Calling Java Libraries
Here’s a short script showing importing and calling the java.lang.System class from a script. Two Java methods result from compiling this script: one for foo and one for the script body itself, which is compiled as the main() for the resulting .class file.
def foo
home = System.getProperty "java.home"
System.setProperty "hello.world", "something"
hello = System.getProperty "hello.world"
puts home
puts hello
end
puts "Hello world!"
foo
Notice also that there are no types declared anywhere in this script. The types of ‘home’ and ‘hello’ within the ‘foo’ method are inferred to be java.lang.String from looking at the getProperty method on java.lang.System. Also, in the current Mirah code, ‘puts’ is treated as a keyword that essentially does a System.out.println of the passed argument. This may or may not be part of final Mirah; or puts may be an extension method applied to java.lang.Object, so it is always present to all scripts.
Constructing Objects
Because Ruby’s standard for object construction is to call a “new” method on a target class, the Java backend uses the same syntax to invoke a constructor on a target type. Here an ArrayList and a StringBuffer are constructed and manipulated. Note again the similarity to Ruby code; if the imports were gone, this script is perfectly valid Ruby code.
import java.util.ArrayList
list = ArrayList.new
sb = StringBuffer.new("Hello")
sb.append(", world")
list.add(sb)
puts list
Note again that no types are actually declared here, and the types of ‘list’ and ‘sb’ are inferred from the results of constructing ArrayList and StringBuffer.
Outputting java code
By default mirah compiles to bytecode, and executes that. You can also convert straight to “java”, like
$ mirahc --java file.mirah # create folder File with .java files in it
How are Java Interfaces Defined/Implemented in Mirah?
class Foo
implements Serializable
....
end
interface A do
def something:void;end
end
interface B < A, Serializable do
def somethingElse(x:int):int;end
end
How do you use an anonymous class?
In general if a method accepts an interface, and that interface only defines one method, then you pass it in as a block.
ref: https://github.com/mirah/mirah/blob/master/examples interfaces
How are exceptions coded in Mirah?
Ruby syntax is used (except retry and catch/throw)
begin
....
rescue IOException => ex
.....
ensure
.....
end
If you want to declare which exceptions a method throws,
use the throws macro.
def foo
throws IOException
....
end
This is only required if you are using the java backend
as the .class backend does not check exceptions.
How to use final
There is not currently a way to declare variables final, but this will likely be added in the future. In addition, we are considering options for declaring entire classes immutable (or mutable only in constructor) and for declaring local variables as write-once (essentially equivalent to final local variables in Java.
Mirah presently opts to present mutable local variables for closures, to better imitate Ruby’s mutable closure scopes. This may change or be augmented with immutable closure scopes in the future.
How to use void
If subclassing a java class or implementing an interface with
a void method, Mirah should be able to infer that automatically.
The only time we need to specify void is if you want to force a
method to return void.
This is particularly useful for chaining methods because Mirah treats
void methods as if they return self.
class A
def foo
puts "foo"
self
end
def bar:void
puts "bar"
end
end
class B < A
end
y = A.new.foo # y is an A
x = B.new.bar # x is a B
How to set visibility (public, private etc.) in Mirah?
Visibility is set the same as in a ruby script.
How to use Java annotations in Mirah?
$Deprecated
def foobar; end
The source code compiler doesn’t support annotation values, but the bytecode backend should support string, class, and annotation values, as well as arrays of those types.
Use square brackets instead of parens around the values:
$Foo["xyz"]
$Bar["a" => "A"]
How to do foreach (for loop)
I believe you do it just by using the “each” method.
import java.util.ArrayList
b = ArrayList.new [1,2,3]
b.each{|n| puts n}
Though in reality it’s just syntactic sugar for a large iterator loop.
How to declare a variable’s type but with value null
p = Printer(nil)
Primitive arrays
str_ary = String[5]
int_ary = int[5]
or an array of any type
classes = Class[1]
classes[0] = Long.class
Operators
NB that currently mirah uses java’s default “a == b” operator if you use “==” within mirah. this is almost always wrong if you are comparing objects, but works for integers and objects with the same object id, so plan accordingly.
Also note that you can name methods with ruby style syntax, like “solid?” and “def +(o:Object); end” and call them using that same method name, just realize these method names are not standard for java, so won’t be easily callable from java, and if you uses mirahc to generate java files from them, they won’t compile with javac as this is a limitation of the java parser. Not mirah though, it can use them.
casting/declaring primitive types
The default value for a number is int or long if the number is large
a = 0 # int
b = 4_000_000_000 # long
a = long(0) # long 0
b = short(0) # short 0
eventually mirah wants to also support “0L” type syntax.
Macros
See https://mirah.org/wiki/Macros for how to implement your own mirah macros them.
Importing
Imports are the same as java, without a need for a trailing colon:
import java.util.HashMap
import java.util.*
you can also rename things for convenience sake:
import java.util.HashMap as H
H.new
Profiling
As with any java program, where ProfileStev.class was created for me by mirah:
$ java -agentlib:hprof=cpu=samples ProfileStev
Re-use Blocks
You can have a method pass you block a block instance, then save that around:
interface BlockOne do
def go3():Object
end
end
class A
def go(o:BlockOne)
o # return the block
end
def go2(o:BlockOne)
puts 'in go2'
end
end
instance = A.new
block = instance.go {
puts 'in block'
}
instance.go2 block
Your question not answered here?
More questions and answers culled from the mailing list are temporarily stored at https://gist.github.com/704274 - feel free to introduce more to the wiki here, or to copy them from that gist to here.
See also MirahSamples