By far the most entertaining and most thought provoking presentation of the JVM language summit was given by Erik Meijer (and by a large margin). Unfortunately, it was not recorded and will not be on InfoQ like many of the other presentations as far as I know. His talk was called Fundamentalist Functional Programming which is basically his way of advocating pure functional languages (read: Haskell although he did mention Clean as well). He argued that any impure functional language is NOT a functional language. Either you are pure or you happen to have some features of functional programming languages. And he did this in a wildly entertaining manner. I've personally been looking at Haskell recently so this talk was very timely and informative. How often do you see a presentation where someone suggests that Computer Science has gone in completely the wrong direction the past 50 years and needs to get back on track and has some ammo to back it up? I think many people in the audience found it entertaining, but not really practical. To that I would ask, why not? How many times a day do you say to yourself "there must be a better way?" Maybe this would be a quantum leap? I'm still exploring Haskell and I think that it might not be the solution, but it might inspire a better way. I've found many people on the Haskell IRC channel (which is extremely active) to be very helpful, but the documentation about Haskell will scare away most programmers. The concepts aren't hard, but if you read the wikibook you will likely come away with the impression that only PhDs in Mathematics can learn Haskell. Real World Hasekll seems better, but still lacks that killer intro that will grab the attention of the masses (and maybe they don't want the masses...). Erik's presentation was passionate and you could tell that he really believes that pure functional programming is the future.
Cliff Click's demo of Azul Systems tool was very, very impressive (and only about a dozen people saw it). His presentation was also good. This type of low level HotSpot support is necessary for language designers who are serious about performance and $40k seemed reasonable for a machine if you get Cliff's expertise along with it!
In addition to some C# by Mads, Allison Randal spoke about the Parrot VM. I was happy to see that Sun had the openness to invite Microsoft and Parrot to take part. I think that it really added to the quality of the summit. Google had some folks present, but didn't really talk about how they use the JVM. Next year, I would love to see some more activity from Google.
Parrot is a register based VM which makes some things (ie continuations) easier to implement, but I think that it might be quite some time before the performance can match the HotSpot JVM for most things. Parrot has been around for 7 years so they just have not had as much time (and money?) to devote to making it as mature as the JVM.
Thinking about going to the JVM language summit next year? I highly recommend the event, but it is a small group of highly experienced language designers. So the following words should not scare you: invariant, covariance, type erasure, continuations, tail call optimization, etc. You probably also should have some experience implementing your own language and/or working extensively at the byte code level. It will also help to be familiar with the symbols used to describe type systems. I don't mean to scare anyone away, but I recommend that you make an honest assessment if the event is right for you. Otherwise you might have a good time but not be able to take part in the conversations. If this is your thing, Microsoft also has a Lang.NET conference you might want to check out.
My only suggestion to Sun: use a room with a screen that is elevated a little more so the entire room can see the full screen.
Summary
- LINQ - Functional programming features in C#.
- Kawa - Scheme without full continuations.
- Fundamentalist Functional Programming - Turn your world upside down presentation. Described in detail above.
- NetRexx - An old IBM scripting language that has been open sourced.
- Scalify - Library to take Java code as input and produce Scala as output. Looking for others to join to add Java -> "other JVM language" implementations as well.
- Closures and the JVM - Mostly discussed language interoperability on the JVM and the problems languages face when trying to use libraries written in other languages (with Java being somewhat of an exception). If you haven't heard by now, Neal is also working for Microsoft.
- Bytecodes for fast JVMs - Showed low level metrics for Clojure, JRuby and Jython. Cliff was able to identify areas where teams thought that something was being inlined, but in fact was not.
- Jatha Common Lisp - What Ola Bini worked on before JRuby.
- Parrot VM - Register based VM.
Many thanks to Sun for hosting a spectacular event. In particular, thank you John Rose for taking the time on several occasions to chat. I know you were very busy.
Well, how often do you get to speak to an employee of Sun, Google and Microsoft in the same day? And not just any employee, but some of their best and brightest? Needless to say, day 2 was loads of fun. And I got to ask Erik Meijer exactly how many tie-dye shirts does he own... I've always wondered that.
Overall impressions: many people here are "into" functional programming languages. Concurrency is another big topic. This conference has just the right blend of academia and "real world" for me. It is very technical, but not so full of Greek letters that your head hurts.
- Gosling keynote - History of Java.
- JavaFX - How they use javac to compile JavaFX.
- JRuby - How they have blazed the trail for dynamic languages on the JVM.
- ASM - The library for byte code manipulation.
- PHP - Not totally sure why, but they are working on it. Overall, I think its good to have as many mainstream languages on the JVM as possible.
- MOP - Metaobject protocol for passing objects between dynamic languages on the JVM. Like the idea, not sure sure about the implementation.
- invokedynamic backport - I can't get enough details about invokedynamic.
- Clojure - Functional language on the JVM. The highlight of the day for me. It's not 100% what I would like to see, but it is the closest yet.
- Python gradual typing - Typing notation makes your head spin, but a very good talk.
- Jython - Sort of opposite situation from the CLR/DLR. On the DLR IronPython came before IronRuby and Ruby.NET and really blazed the trail. On the JVM Jython has been around, but they seem to be in a complete re-write and are really leveraging a lot from JRuby (and that is very, very good).
Final observation: I'm very impressed with how approachable the 80 or so odd people here are, especially the Sun employees. Granted they are the hosts, but they have really taken their time to interact with the participants (as they should because I really don't think that they would want to alienate this crowd in particular!).
JVM Language Summit - Day 1
Day 1 of the JVM language summit in Santa Clara has come and gone. The agenda can be found at Agenda.
The highlight of day 1 for me was John Rose talking about invokedynamic. A lot of attendees really liked the talks about Fortress and multiple dispatch, but invokedynamic was the most relevant to me. And best of all a Sun employee said that invokedynamic would be part of Java 7. Now, that doesn't mean anything, but it is encouraging to hear that Sun is committed to getting it included in Java 7.
The surprise of the day for me was the presentation on Fan. I had not heard of fan prior to signing up for the event. It seems like it is still pretty immature, but it is interesting. The language is being created from the ground up to run on the JVM and CLR. They have spent most of their time making libraries that can be built on top of both platforms. The big problem is that you can't call out to the multitudes of libraries available on those platforms. This is a show stopper for now.
Stu's lightning talk started the best conversation of the day. The open sessions, or unconference or whatever term you prefer, were not nearly as successful at getting people talking about issues as Stu's presentation. The conversation focused on how libraries can be provided on the JVM in the best of breed language for that particular problem and just as importantly how the library can be used by other languages on the JVM. This second part is the part that there is no clear answer for right now. Clojure's collections and the regex library in JRuby were used as examples of libraries that could be shared by lots of languages implemented on the JVM.
Summary
- Hotspot - Just an intro to the event.
- invokedynamic - Read headius' blog if you'd like to know more.
- Maxine - An experimental VM. Not compliant yet. Has an API.
- Fan - new language to run on JVM and CLR.
- Groovy - Intro to Groovy
- Scala - Focused on one aspect of Scala
- Fortress - Fortran on the JVM with concurrency, lots of it. They came the most prepared to make recommendations to Sun of features that could be added to the JVM. The list contained things like continuations, value objects, etc.
- Multiple dispatch - Professor's implementation of how multiple dispatch could be done on the JVM quickly and without too much disruption.
A friend came to me recently and posed an interesting problem. Given a number n how many valid balanced open/close parenthesis combinations are there?
Examples:
n == 4
- ()()
- (())
n == 6
- ()()()
- (()())
- ()(())
- (())()
- ((()))
His solution:
- The number n must be even
- Treat '(' as 1
- Treat ')' as 0
- The minimal value will be "10" n/2 times. ie 101010
- The maximum value will be "1" n/2 times followed by "0" n/2 times. ie 111000
- The odd parity must be n/2
- The even parity must be n/2
- The combinations must be well formed ie (()) and not ))((
The algorithm to solve the problem went like this: Say n is 8, loop from 10101010 to 11110000 by 2's (to exclude odd numbers), make sure that the even parity equals n/2 and that the odd parity equals n/2. For each number loop over the bits and add +1 for 1 and subtract -1 for 0. Throw out any number that goes below 0 at any point.
This algorithm will get you to the correct solution but the solution involved heuristics and considered some invalid combinations. I was sure that there was a way to solve this problem without considering any invalid combinations and I was right. Here is my solution (with an implementation in ruby):
Note: I would not be surprised if there is a mathematically more efficient way to solve this problem, but this is what I came up with.
- Create a grid of all the possibilities.
- Create a directed graph.
- Walk the graph from the end to the beginning.
I am including four figures now that I will reference below.
Create a grid of all the possibilities. Thinking in terms of a turn based stack, the blue squares in figure A can be ruled out as invalid.
Create a directed graph. Again thinking in terms of our stack, there are only two possible operations, push and pop. So as we move from turn 1 to turn 2 we must go either up and to the right OR down and to the right. I also consider the two possible incoming points because my directed graph is bi-directional (think in terms of a doubly linked list). So for the point (0,0) we can see the four possibilities in figure B. They are (-1,1), (-1,-1), (1,-1) and (1,1). Of these four only the point (1,1) falls in a yellow square and is therefore "valid". We then move on to this point and repeat the process until we end up at point (n,0) which is always our last point. At this point our data structure looks like diagram C.
Finally, we have to walk our structure to determine all the valid combinations. My first thought was to walk from the point (0,0) to (n,0) but I ended up walking from the end to the beginning! (Either way works, but I found the code easier to write going in the opposite direction). Using the labels from diagram D we see the valid combinations are:
- J I H F D B A
- J I H E D B A
- J I H E C B A
- J I G E D B A
- J I G E C B A
And finally, the ruby code!
class DirectedBinaryGraphNode
attr_accessor :last_lower, :last_higher, :next_lower, :next_higher, :x, :y
def initialize(x,y)
@x = x; @y = y
end
def to_s()
"#{x}, #{y}"
end
end
def validate_node(n,index)
x = index[0]; y = index[1]
width = x >= 0 and x <= n
vertical = (x < (n/2)) ? x : (n-x)
height = (y >= 0 and y <= vertical)
x <= n and width and height
end
def ensure_node(index,n)
if ( @nodes[index] ) then
node = @nodes[index]
else
node = DirectedBinaryGraphNode.new(index[0],index[1])
@nodes[index] = node
create_node(n,node)
end
node
end
def create_node(n,node)
puts "creating node #{node}"
last_lower = [node.x-1,node.y-1]
last_higher = [node.x-1,node.y+1]
node.last_lower = ensure_node(last_lower,n) if validate_node(n,last_lower)
node.last_higher = ensure_node(last_higher,n) if validate_node(n,last_higher)
next_lower = [node.x+1,node.y-1]
next_higher = [node.x+1,node.y+1]
node.next_lower = ensure_node(next_lower,n) if validate_node(n,next_lower)
node.next_higher = ensure_node(next_higher,n) if validate_node(n,next_higher)
end
def create_data_structure(n)
@nodes[[0,0]] = DirectedBinaryGraphNode.new(0,0)
create_node(n,@nodes[[0,0]])
end
def walk_data_structure(str,last)
if ( last.last_lower) then
walk_data_structure("(" + str,last.last_lower)
end
if ( last.last_higher) then
walk_data_structure(")" + str,last.last_higher)
end
unless last.last_lower or last.last_higher then
@cnt = @cnt + 1
puts "Valid combo: #{str}"
end
end
n = ARGV[0].to_i
unless ( n % 2 == 0 ) then
puts "invalid parameter #{n} [it must be even]"
exit -1
end
@nodes = {}; @cnt = 0
create_data_structure(n)
walk_data_structure("",@nodes[[n,0]])
puts "Total number: #{@cnt}"
Here is a fully functional pom file that works with easyb 0.8 and maven-easyb-plugin 0.8.
<project>
<modelversion>4.0.0</modelversion>
<groupid>com.trial.easyb</groupid>
<artifactid>easyb-trial</artifactid>
<version>0.1</version>
<dependencies>
<dependency>
<groupid>org.easyb</groupid>
<artifactid>easyb</artifactid>
<version>0.8</version>
</dependency>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>4.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>easyb</id>
<url>http://www.easyb.org/repo/</url>
</repository>
</repositories>
<pluginrepositories>
<pluginrepository>
<id>easyb</id>
<url>http://www.easyb.org/repo/</url>
</pluginrepository>
</pluginrepositories>
<build>
<plugins>
<plugin>
<groupid>org.easyb</groupid>
<artifactid>maven-easyb-plugin</artifactid>
<version>0.8</version>
<executions>
<execution>
<goals>
<goal>test</goal>
<goal>storyReport</goal>
</goals>
</execution>
</executions>
<configuration>
<easybtestdirectory>${basedir}/src/test/stories</easybtestdirectory>
<storyreport>${project.build.directory}/easyb-stories.txt</storyreport>
<xmlreport>${project.build.directory}/easyb/report.xml</xmlreport>
</configuration>
</plugin>
</plugins>
</build>
</project>
Gotchas (at least it got me). For the maven-easyb-plugin easyb:storyReport goal:
The pom file xmlReport configuration has a default value which is:
If you change it (as per the maven-easyb-plugin documentation) be sure to change the the storyReport which is being renamed to xmlReport to help avoid confusion:
So, to recap, if you change the value in the pom.xml file you MUST also pass in the storyReport (soon to be renamed to xmlReport) parameter to maven and they have to match.
Pattern Matching: What is missing?
Useful error messages. Huh? Why? What are you proposing?
When all goes well
The code block associated with the case is executed. All is fine here.
When there is no match
A scala.MatchError exception is thrown. Herein lies the problem. As a developer, I get a MatchError exception with a string that says that there was a match error. If I look at the stack trace I can even figure out where things went wrong in the code. But why can't I provide the match statement a String with a more developer/user friendly error message? Why can't I say what there was no match for? For example, suppose I am matching days of the week. Wouldn't a message like "Unable to match the day of the week." be more useful then a general error simply stating that a MatchError was thrown?
When there is a type mismatch
If the data type of the thing being matched cannot be applied to any case in the match that gets executed a scala.MatchError is thrown. Since this is a different type of error I would contend that it is fine as is.
Proposed modification
What if the match was passed a string with a user/developer friendly error message? It might look something like this:
val user = "harry"
user match "Unable to match the name against the list of Weasley boys" {
case "fred" =>
println("this would not be good")
case "george" =>
println("this also would not be good")
case "ron" =>
println("again, not good")
case "percy" =>
println("still not good")
}
So instead of seeing:Caused by: scala.MatchError: harry
You could see:
Caused by: scala.MatchError: Unable to match the name against the list of Weasley boys
Hmmm... it seems that we are still missing the value that wasn't matched, so what about a Function?
val user = "harry"
user match (n) => "Unable to match the name " + n + " against the list of Weasley boys" {
case "fred" =>
println("this would not be good")
case "george" =>
println("this also would not be good")
case "ron" =>
println("again, not good")
case "percy" =>
println("still not good")
}
Or the ultimate version:
Caused by: scala.MatchError: Unable to match the name harry against the list of Weasley boys
So to summarize, I would like to see match modified to be 1 of 3 possibilities:
- As is :)
- Match would take a string and use that as the message
- Match would take a callback function and pass it the value not matched
Tuples
A tuple is a fixed size data structure that allows data to be of different types. Scala has a convenient syntax for tuples that looks like this:(1, 2.0, "three")Tuples are typically used instead of Lists or Arrays when the data types of the objects are not all the same.
Case Classes
In scala a case class is a special type of class (with some restrictions) that "exports its constructor parameters". So what does that mean? It means that you conveniently create and compare instances of the class. Pattern matching will even allow for some of the values to be compared and others to be set in one operation!case class Foo(firstData:Int, secondData:Int)
Pattern Matching
First, pattern matching is a glorified switch statement.
x match {
case 1 =>
println("x is 1")
case _ =>
println("x is not 1")
}
val x = Foo(3,5)
x match {
case Foo(z,5) =>
println(z)
case _ =>
println("we didn't have a match")
}
This says try to match the value of x and when you find a case that is true, execute the code block associated with that case. Don't forget that _ in Scala is like a wildcard character so it is like a set of all values except for the values from the previous case blocks because they were executed earlier. Scala's only advantage over Java here is that you can use objects and not just primitives or Enums for comparison.
Second, pattern matching is like built in assertions (well, sort of).
x match {
case 0 =>
println("x is 0")
case 1 =>
println("x is 1")
}
So in this contrived binary checker, we check x for a value that is either 0 or 1. So what would happen if x contained a value that was NOT 0 or 1? A scala.MatchError exception would be thrown! This allows for a clean form of defensive programming in that the developer does not have to handle all of the possible error conditions right here in the code. The developer can code the "sucess cases" and let exceptions be thrown for the exception cases and those exceptions can be handled by an error handling layer someone else in the code.
Third, pattern matching is useful for variable assignment
(assigning multiple variables on one line, assigning only certain variables, etc) This is where tuples enter the picture again.val a = (1,2.0,"three") val (d,e,f) = a println(d) println(e) println(f)This will produce the following results:
1 2.0 threeAdditionally, you could do:
val a = (1,2.0,"three") val (b,2.0,"three") = a println(b)This will print out 1 as expected. But NOTE that if the values in the second and third positions of the tuple did NOT match then an exception would have been thrown! So you could NOT do:
The following example would throw an exception!
val a = (1,2.0,"three") val (b,2.0,"3") = a println(b)
Many people like to think of pattern matching in this way.
- Do all of the bound variable values match?
- If yes, then we have a match!
- If not, what could the code do to make the statement true? (ie assign a value to an unbound variable...)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>mvn.scala.test</groupId>
<artifactId>mvn.scala.test</artifactId>
<name>Maven Scala Plugin Test</name>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<description>
Test for Maven Scala Plugin.
</description>
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
<repository>
<id>jline</id>
<name>JLine Project Repository</name>
<url>http://jline.sourceforge.net/m2repo</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
<version>0.9.94</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<testSourceDirectory>src/test/scala</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.example.HelloWorld</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Some points of interest
Ok, so the first thing you might notice is that I have to have two explicit dependencies: jline and scala itself. maven-scala-plugin will compile your code without the scala dependency, but it cannot run the classes unless the jar is provided at runtime via a dependency. Jline I determined was required by simple trial and error.
The scala-maven-plugin site's documentation is incorrect. The group id is not "scala" as they claim, it is in fact: <groupId>org.scala-tools</groupId>
The sourceDirectory and testSourceDirectory do not have to be specified if you decide to use src/main/scala and src/test/scala (at least according to their documentation) but I have chosen to explicitly state them here anyway.
So, you need to put your scala code in src/main/scala and your tests in src/test/scala. The typical HelloWorld example could be saved to src/main/scala/HelloWorld.scala which looks like:
package org.example {
object HelloWorld extends Application {
println "hello"
}
}
Then from the command line run:
mvn clean compile
mvn scala:runAnd voila, you should see "hello" print to the console.
Concurrency in Java is a nightmare. I used to think that when I first started using threads. After getting the hang of it a little I thought maybe, just maybe it wasn't so bad. Then I saw Brian Goetz speak at No Fluff and I realized that the state of concurrency in Java is impossible for a mere mortal to comprehend. Whenever a topic becomes too difficult, I have learned to step back and look at the big picture. There must be something that I am fundamentally doing wrong. I think that this is one of those situations, only it took over a decade for most of us to figure out, while a small group of people were shaking their heads the whole time.
That small group of people are the developers who understand functional programming languages. Functional programming languages do not have shared state. This makes concurrency in them a joy when compared to Java and most OOP languages. I recently took some time to start learning Erlang (Pragmatic Studio, very well done Joe and Dave!) and I was very impressed with what I saw. I really loved some of the aspects of Erlang. It is well known for having concurrency baked into its DNA, but I was impressed with several other things (things I had seen before, but just felt so natural in Erlang). Higher order functions, list comprehensions, hot deployment, and most importantly pattern matching. This isn't an blog about any of those topics however. This is about concurrency and in the title I mentioned concurrency on the JVM.
One of the things that I did NOT like about Erlang was that the sequential programming features seemed incomplete to me coming from an OOP world. Not to mention commas, semi-colons, periods and nothing... and when to use which! I remember wishing in class that Erlang ran on the JVM so I could use it for all my concurrency needs and call out to Java/JRuby/Groovy/SISC/etc for the meat of my application logic. Using the xmerl library (I know that there is a better one out there, but c'mon no xml library should be this difficult) made me really long for something better. So once again I took a step back and tried to look at the big picture.
Before going to the Erlang Pragmatic Studio I had started to read up on Scala (which I find difficult because I find the documentation to be very sparse and fairly poor) and Scala's actor library in particular. I admit that when I first looked at it I didn't fully get it. Learning Erlang helped cement some concepts that make looking at the Actor library much, much simpler. While I still prefer the Erlang way of receiving messages in particular I found the Scala Actor library to be decent. It is also worth nothing that the Scala actor library works with threads or with processes (actors, not OS processes). To me, the whole reason to use the actor library is to NOT be using threads, so I highly recommend the event based actors.
Actor concepts
In an actor based concurrency model, there are 3 fundamental concurrency primitives. First, there is spawn. Spawn creates a new actor which has a mailbox where it can receive messages. In Erlang spawn spawns functions and in Scala the equivalent is creating a new Actor and starting it. (Think creating a new thread and starting it). The second primitive is send (!). This is pretty similar in both Erlang and Scala. receiver ! message means send message "message" to "receiver". Scala actually has some additional methods for sending messages but we won't cover them here. Finaly there is receiving messages where a message is pulled from the mailbox if it matches a pattern and can be acted upon. Erlang blows away Scala on pattern matching from what I can tell, but I am admittedly not an expert on Scala pattern matching.
So some important topics to discuss now: What is an Actor, immutable state and pattern matching, and process linking.
What is an actor?
An actor is like a thread but without shared state. I sometimes refer to it as an programming language process because an actor is a process, but not an operating system process. It is a process that is managed by the runtime process and therefore must be very lightweight. Erlang has spent a lot of time getting processes very light weight. Erlang doesn't use the term actor, it just has processes, but they are the same thing. Each process or actor has a mailbox where it receives messages from other processes. Messages are the ONLY way that processes can communicate since they have no shared state.
Immutable state and pattern matching
Immutable state is key to functional programming languages as they are intended to have no side effects and immutable state means that no function can change the value of something (a variable) and thus introduce a side effect. Pattern matching in Erlang is brilliant. It matches the left side and the right side of the =. Conceptually there are 3 things that can happen here. If the left is unbound it will be bound with the value from the right side. This looks like variable assignment from OOP. If the left side is bound it must match the value from the right side or an exception will be thrown. This is because variables are immutable and they cannot be "assigned" another value. Finally, if the left side has a partial match it can assign values to unbound variables that match the pattern. A tuple is the simple way of understanding this.
A = "a",
B = "b",
{A,C} = {A,B}
This will match because the left side and right side are tuples of the same size and none of the matching values would change state. Since A equals A we are OK. And since C is unbound it will be assigned the value from B.
A = "a",
B = "b",
{A,B} = {A,C}
This would not match because C is unbound.
Likewise, the following would not match because the values of B and C do not match:
A = "a",
B = "b",
C = "c",
{A,C} = {A,B}
Fault tolerance
So if you have heard of Erlang, you have probably heard that it makes concurrency and fault tolerance easy. We've looked at the concurrency primitives, but what about the fault tolerance primitives? They are link, unlink and process_flag. These are conceptually simple. If a process A links to process B then they are linked. If one dies then it will send a signal to all the processes that it is linked to prior to its own death. The linked processes can be system processes depending on whether or not they set their process_flag. If they did then they can trap exit messages from dying processes, if not then this process will die as well. So as you can probably imagine it is easy to create graphs of processes that will die when certain failures occur and that can be restarted or resurrected by some system processes. Scala's actors have these concepts as well. I won't go into any more detail about them here, but if you read the links at the bottom of this blog you can find some additional information in the Scala actor api.
So now that I have given a very long winded ill-explained description of actors, let's look at a real example in Erlang and in Scala:
Erlang
-module (blog).
-compile(export_all).
client(Pid) ->
Pid ! {self(),request,foo},
receive
{Pid,response,Response} ->
io:format("got response ~p~n",[Response]),
Pid ! exit
end,
io:format("client done~n").
server() ->
receive
{From,request,Request} ->
io:format("got request ~p~n", [Request]),
sleep(1000),
From ! {self(),response,bar},
server();
_ ->
io:format("server done~n")
end.
sleep(Time) ->
receive
after Time -> void
end.
foo() ->
Pid = spawn(fun server/0),
spawn(fun() -> client(Pid) end),
exit.
Scala
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.OutputChannel
case class Request(data:Object)
case class Response(data:Object)
case object Exit
class Client(server:Actor) extends Actor {
def act() {
server ! new Request("foo")
react {
case Response(data) =>
Console.println("got response " + data)
server ! Exit
println("client done")
exit()
}
}
}
class Server() extends Actor with Sleeper {
def act() {
loop {
react {
case Request(data) =>
println("Got request " + data)
sleep(1000,(sender:OutputChannel[Any]) => {
sender ! new Response("bar")
},sender)
case _ =>
println("server done")
exit()
}
}
}
}
trait Sleeper {
def sleep(time:Long,fun:(OutputChannel[Any])=>Unit,sender:OutputChannel[Any]) {
reactWithin(time) {
case _ =>
fun(sender)
}
}
}
object Foo extends Application {
var s = new Server()
var c = new Client(s)
s.start
c.start
println("exit")
}
So what does it do?
This code spawns two actors, 1 as a client and 1 as a server. The server listens for request messages and responds with response messages after sleeping for 1 second. If a message comes in that is not a request message, then the server exits. The client sends a request message to the server and then listens for the response. Once it receives its response it sends a message to the server that is not a request as a shutdown command. Not particularly interesting, but it does demonstrate some of the key differences between Erlang's processes and Scala's actors. One of the biggest differences is that a receive in Scala is a method that does not return. This means that any logic must be present in the receive and all code after the receive will never be executed. Erlang can pattern match on atoms and tuples and Scala pattern matches on case classes. One of Erlang's strong points is distributed code. In Erlang, when a process is spawned there can be no knowledge of whether or not that process is running on the same machine or remotely. It simply doesn't matter. Scala has remote actors as its equivalent, but the things I've covered here so far are really for replacing threads within a single JVM. The concepts don't change and maybe that will be the topic of a future blog post.
Resources:
- Scala
- Scala Actors
- Erlang
- Ruby Actors
Update
If you did not need the sleep function, you could use this shorthand notation to define the actors. Notice that the server actor is assigned to a variable that the client actor uses.
import scala.actors.Actor
import scala.actors.Actor._
case class Request(data:Any)
case class Response(data:Any)
object Foo extends Application {
actor {
server ! new Request("foo")
react {
case Response(data) =>
Console.println("got response " + data)
server ! "Exit"
exit()
}
}
var server = actor {
loop {
react {
case Request(data) =>
Console.println("got request " + data)
sender ! new Response("bar")
case _ =>
println("exiting server")
exit()
}
}
}
}
We often have the need to create data. We use data for integration tests, to populate database tables in production for releases, and many, many other reasons. This article talks about one way to get data into your database in a way should allow for it to be modified without too much trouble when those changes come your way in the not so distant future...
Is this even a good idea?
Something that occurred to be recently is that builders, as implemented in Groovy (or JRuby for that matter), might be a good way to create and manage test data for some Java unit tests. But I wasn't really sure, so I set out to determine if in fact it was a good idea or not. If you aren't familiar with builders, read Builders. For better information, read Manning's Groovy in Action. From now on, I will assume you are already familiar with builders. If you are too lazy to follow the links, builders lend themselves to displaying tree based data structures well because the code is in a form that visually represents the data structure. It does this by using some neat meta-programming tricks and closures. If you aren't familiar with meta-programming or closures you might want to read about them first as well. Wikipedia probably has better information on closures. [Wikipedia Closures]
What about XML?
In the past I have used xml to manage data for unit tests and in theory this means that Java objects or XSLT can be used to modify the data. However, in practice, while either is adequate for modifying test data, neither is particularly simple or elegant. Adding columns, modifying relationships, etc is typically not a trivial task when the data is in xml. Let's be honest (and I can't believe I'm about to put this in writing), for test data, I want to modify it in a Spreadsheet (Excel or Open Office's Spreadsheet or iWork Numbers). Why? Well, because adding and removing columns is simple, macros are supported, copy and paste is simple, etc. So why am I bringing this up? Well, how about because data in a builder (a tree) can be exported to csv with very little code, modified and imported back into the builder with minimal code. So why not store the data in csv format then? I cannot think of any compelling reasons not to as a matter of fact, especially if you were to use the same data for tests in different languages! But for now, I am keeping my data in groovy code, code that I believe is very readable. (To be fair, you could go from xml to csv and back again, but reading and manipulating xml is more difficult than reading the same data in the builder tree. I have included the code below that goes from a builder to csv and back. I challenge you to write code that does the same for xml. It might be possible, but I believe that most, if not all, people would have to write more code to achieve the same result. If you decide to keep your data in csv and not groovy then it might be a perfectly acceptable alternative to use xml, I'm not knocking it, I just think it can be done in a simpler way.)
Trees vs. Graphs
Your first thought might be, well data for unit tests is probably an object graph, not a tree! The data is most likely going to go into a RDBMS after all. While this is true that the data is a graph, it can be represented as a tree(s). A node in the tree can point to another node in the tree, not just one of its parent nodes. Think xml refs if you are having a tough time following the idea. The problem is that unlike xml refs there is no check to verify that the other end of the connection exists. Therefore, I suggest loading the data into a RDBMS and let it do what it is good at, enforcing the relational integrity. For testing, I suggest an in memory database like HSQL. As an aside, dividing the data into logical groups is also a good idea. (This can be done regardless of whether you use a tree or a graph.) It allows us to manage logical data sets independently. For example, I might have users and roles which are kept separate from office locations.
Referential Integrity
Pointers to data in other tree nodes are not referential so data integrity is not ensured. Again, you are probably thinking, it sounds like I am trying to convince you that builders are NOT appropriate for creating and managing test data, but wait... the database can do it and do it well. So why not let the db do that work for you? Since the data itself does not guarantee the referential integrity you do not get static analysis time protection. However, you can create unit tests that insert your data into an in memory data base and this will ensure that your data has its referential integrity. Assuming of course that you run your unit tests and that you have foreign key relationships!
Data Builders and Data Persisters
So, what does this code look like? We'll get to it shortly. But first, let's talk about what the "real" code will do? Well, there are 2 primary things for each set of data.
Data Builders
First, there is the data builder which is our tree of data. This is a groovy file that contains our actual data values. An example: def getData() {
new NodeBuilder().users {
user(user_id: "123", first_name: "Joe", last_name: "Smith") {
address(address_type: "home", street: "123 Main St.", city: "Springfield", state: "MA", zip: "12345")
address(address_type: "work", street: "456 South St.", city: "Boston", state: "MA", zip: "98765")
}
user(user_id: "456", first_name: "John", last_name: "Doe")
user(user_id: "789", first_name: "Jane", last_name: "Doe")
}
}
Data Persisters
Then there is our persister, which in our case uses GPath (similar to XPath, but walks Groovy objects) to pull data out of the builder and persist it. In my case that means populating Hibernate objects and then saving the hibernate objects. def persist(tree) {
tree.grep() {
User user = new User()
user.userId = it.@user_id
user.firstName = it.@first_name
user.lastName = it.@last_name
it.address.grep() { address ->
Address addr = new Address()
addr.addressType = address.@address_type
addr.street = address.@street
addr.city = address.@city
addr.state = address.@state
addr.zip = address.@zip
user.addresses.add(addr)
}
userDao.save(user)
}
}
We separate these objects so that multiple data sets can be used depending on the environment or test suite. In other words, it is good to keep the data separate from the code that will manipulate the data.
The data
As an example, let's suppose we want to add some users to our database. Let's assume that there are 3 users and the first user has 2 addresses. The tree might look something like this in csv format:
users ,user,user_id,123,first_name,Joe,last_name,Smith ,,address,address_type,home,street,123 Main St.,city,Springfield,state,MA,zip,12345 ,,address,address_type,work,street,456 South St.,city,Boston,state,MA,zip,98765 ,user,user_id,456,first_name,John,last_name,Doe ,user,user_id,789,first_name,Jane,last_name,DoeWhat might this data look like in xml?
<users>
<user user_id="123" first_name="Joe" last_name="Smith">
<address address_type="home" street="123 Main St." city="Springfield" state="MA" zip="12345" />
<address address_type="work" street="456 South St." city="Boston" state="MA" zip="98765" />
</user>
<user user_id="456" first_name="John" last_name="Doe" />
<user user_id="789" first_name="Jane" last_name="Doe" />
</users>
And in groovy?
users {
user(user_id:"123",first_name:"Joe",last_name:"Smith") {
address(address_type:"home",street:"123 Main St.",city:"Springfield",state:"MA",zip:"12345")
address(address_type:"work",street:"456 South St.",city:"Boston",state:"MA",zip:"98765")
}
user(user_id:"456",first_name:"John",last_name:"Doe")
user(user_id:"789",first_name:"Jane",last_name:"Doe")
}
Which do you find to be the most readable? Some will say xml, most will say groovy. But more importantly, the impedance is zero for groovy because it is already groovy code and no transformation is necessary. Whereas, if we have xml some transformation is necessary.
Let's suppose that we also have a Role table for securityroles ,role,role_type,admin,description,System Administrator ,role,role_type,data_entry,description,Data EntryWhat if we wanted to have a reference from a user to a role or vice versa? Imagine something like this snippet:
user,user_id,123,first_name,Joe,last_name,Smith ,role,admin ,role,data_entry
Getting back to an earlier point, seeing this should probably scare you a little. The string (think symbol if you like ruby or atom if you like many other programming languages) 'data_entry' is entered in two places so if it is modified in one place our structure breaks down. Well, with foreign key constraints in your db this should be solved for MOST (but not all) cases.
Isn't it about time for some code?
Code to convert a Builder to csv:
def print_csv(node,indent) {
def result = ""
result += "," * indent
result += "${node.name()},"
node.attributes().each { attribute ->
result += "${attribute.key},${attribute.value},"
}
result += "\n"
node.grep() { child ->
result += print_csv(child,indent+1)
}
result
}
Code to convert csv to a Builder:
def static read_csv(str) {
def lasts = []
def root
str.split('\n').each {line ->
def arr = line.split(',')
def depth = 0
// determine depth
while ( arr[0] == "" ) {
arr = arr[1..<arr.size()]
depth++
}
// determine parent node
def parent
if ( depth == 0 )
parent = null
else
parent = lasts[depth -1]
// create new node
Node node = new Node(parent,arr[0])
// is this our root?
if ( lasts.isEmpty() ) {
root = node
}
lasts[depth] = node
// process attributes
def key = null
arr[1..<arr.size()].each {
if ( key == null ) {
key = it
}
else {
node.attributes().put(key,it)
key = null
}
}
}
root
}
Conclusion
So is keeping data in this format for unit tests a good idea or not? That's for you to decide!
Footnote
PS After writing this code, I became aware of the ObjectGraphBuilder in Groovy, which allows for relationships between nodes in the tree, but only to parent nodes. Since we are interested in relationships to nodes in other branches or other trees I haven't seen a compelling reason to switch to the other Builder implementation yet.
- Adhearsion
- RSpec
- Solr
- Metasploit
VOIP library built on top of Asterisk (which sounds awful to have to use). Demos were cool. Test coverage was ... low to put it mildly. :)
RSpec
RSpec unit testing is fine, demo of ping pong development was simple, but the merge of another test framework (Fit I think? I can't recall for sure.) into the soon to be released RSpec version was simply awesome. Hats off to the team for getting me interested in testing again for the first time in quite some while. Basically, they've designed a DSL for BDD and a really cool looking UI. I've read a fair bit before on BDD but never really saw what distinguished it from TDD to make me investigate it further. I'm actually looking forward to the new version of RSpec being released now so I can start testing RSpec BDD style. There are 3 ways that the new framework can be used: pure ruby, dsl and I forget... (probably some variation of the first 2). The dsl version basically split the description part into a dsl (in theory to be used by "business users", which would almost never happen in practice) and the implementation part was still in ruby. Ryan D. had a problem with the dsl version because it was too far away from ruby syntax, but no one in the crowd backed him up. In fact, I think it is a positive. I'd like to see JBehave and other BDD frameworks adopt the dsl so that tests could be written for any scenarios regardless of the implementation language!
Solr
So its been a little while since I last used Lucene, but I really liked this presentation and I thought it was one of the most relevant talks. Solr basically exposes search via http. I have some questions about using solr for federated searches which I'll be investigating further myself, but I'm sure that a significant percentage of projects have the need for something at least similar to solr.
Metasploit
OK, I've seen metasploit before, but its been ported from perl to ruby (the part of it that was in perl anyway)... so now its assembly, c and ruby. And let's just say that attaching irb to running processes on remote boxes is way too easy and way cool.
Honorable mention
Justin's talk on identity (OpenID and CAS) was very practical and useful and rubigen might come in handy some day, but the presentation had too much video and not enough let's roll up our sleeves and write some code examples.
- IronRuby, JRuby and Rubinius
- Mac OS X Loves Ruby
- Matz Keynote
MRI (CRI) vs. IronRuby vs. JRuby vs. Rubinius vs. YARV
IronRuby, JRuby and Rubinius presentations opened the day. Nothing too new here. IronRuby is the port of Ruby to .NET. It has the farthest to go. JRuby is pretty far along. Rubinius contends that ports shouldn't be to .NET or the JVM, but to ruby itself, at least for as much of the runtime and kernel (read standard libraries) as possible. IMHO this would make the jobs of the IronRuby and JRuby teams much easier, but unfortuantely, Rubinius is not complete so they cannot build on top of Rubinius. YARV is the much anticipated Ruby 1.9 virtual machine that promises significant performance improvements, but it wasn't really discussed in detail at this point.
Mac OS X Loves Ruby
Focused on Leopard. In particular focused on RubyCocoa and DTRACE. The RubyCocoa examples were visually cool. One used Ruby to open a GUI and make it read a message out loud. XCode was used as the ruby editor, which it appears Apple is trying to coerce developers into using. The GUI was built using drag and drop in XCode and the ruby code was tied to GUI components by clicking and dragging in XCode. Another example used a script to attach ruby to a running process (TextEdit) and manipulate the process (resize, change window name, change editor text) real time in irb. This example was particularly interesting and grabbed my attention from a security standpoint. While this stuff was cool, I don't write software only for OS X so I won't be touching any of it. DTRACE is for debugging operating system calls by applications and it is included with Ruby on Leopard.
Matz Keynote
Focused mainly on Ruby 1.9 and 2.0 features. 1.9 is a transitional release that breaks compatibility with 1.8.6 syntax. Ruby 1.9 will be released before the holiday season, ie end of 2007, but it seems like it might be a historical footnote. In fact, Ruby 1.8.6 will still be the production stable release. Ruby 1.9 will switch from green threads to operating system threads. 1.9 introduces (somewhat controversially) parameters after optional parameters. Matz cleared up the air by stating that this was a transitional stage on the way to named parameters which will be added at some point in the future.
Oh, and everyone in attendance is aware that tonight is daylight savings time.
- Jim Weirich's presentation on Advanced Ruby Class Design
- Nathan Sobo's presentation on Treetop
- Ryan Davis' presentation on Hurting Code for Fun and Profit
Advanced Ruby Class Design
Well done presentation specifically tailored to developers coming from Java or C#. Included examples from some of the most mature ruby libraries around. Jim wanted to present examples that were fun and interesting and he delivered.
Treetop
I had to choose between this presentation and ropes. I'd still like to learn more about ropes someday, but I'm really glad I went to this presentation. Treetop isn't for everyeone, but I love the ideas behind Treetop and I can't wait until it is slightly more mature (and [better] documented). I've already downloaded the gem (and facets as it is required) and played with Treetop a little. My first impression is that it does not work in JRuby 1.0.1 at all which is unfortunate. I'm not sure if this is a JRuby bug, a problem with something in facets or a problem with Treetop itself. UPDATE Recently released JRuby version 1.1b1 fixes the problem so it was a JRuby bug. Hopefully Treetop will be replacing Gold Parser Builder and antlr in my mythical developers toolbox soon. This project embodies the ruby community for me, it is approaching a very old problem in a very new way (admittedly Nathan isn't the idea originator, but who is doing parsing this way in the Java/.NET world?) and a very ruby way.
Hurting Code for Fun and Profit
A non-technical presentation, but very entertaining and relevant presentation nonetheless. I almost passed on this presentation because I thought the presentation was oddly named and the extract contained words like "ascetic" which I did not know the meaning of. And the reference to "for fund and profit" ("Smashing the stack for fun and profit" being the reference, at least, that's the first reference to "for fun and profit" that I'm aware of) didn't really seem to make sense either. So what exactly is hurting code? Well, it turns out that it is hurting (refactoring/re-writing/modifying) code that you do not like instead of hurting the offending developer(s). Code that "you do not like" is very open to interpretation and Ryan basically defined it as code that doesn't sit well with you (instinctual) as opposed to some concise algorithmic approach. The presentation did mention a couple of tools (all developed by Ryan I believe) that could potentially help detect code that probably should not sit well with you, but they were not really the focus of the presentation.
Looking forward to day 2!
So what are some arguments against this type of pattern? Well, many people complain about the following points: (1) the code is no longer as readable, (2) the visibility of the code is changed, (3) the potential explosion of classes, and (4) the logic of an "Object" is no longer contained within the class. Let's discuss these points one at a time. Code samples are included below for a side-by-side comparison so read the code and think about it as you go through the four points.
1) The code is no longer as readable. This may be the point with the most merit. Instead of reading the code and simple scrolling up or down to continue reading the reader must now find another class. Having a method name on the called class that is descriptive often makes the code just as readable, it simply requires the reader to go to another place to read the details of the implementation. IDE's alleviate this by allowing users to jump to other classes/methods.
2) The visibility of the code is changed. Instead of having a private or protected method inside of the class there is now an often times public method on another interface/class. However, the scope of the collaborator can be controlled inside the class so in my opinion the benefit of testability outweighs the changing of scope from method to field.
3) The potential explosion of classes. Methods can still be grouped together on collaborators by related functionality, but having a few extra classes is an acceptable trade-off for more testable code. Classes often tend to be simpler with this methodology. This can become an argument of preference between fewer, more complex classes or more classes that are simpler.
4) The logic of an object is no longer contained with the class. But it can be contained within a small number of classes in the same package and the classes tend to be simpler and classes tend to be even more well defined in terms of what they do.
There probably is no right or wrong answer here, to a degree it is a matter of preference, however, I feel pretty strongly that having more testable code without any major drawbacks is worth adopting this pattern. This pattern works particularly well when the called code is a stateless service that can be injected by an IOC container, such as Spring.
Let's look at samples side by side.
# All the logic in one class (NOT easily testable because bar must be tested with foo)
public class Foobar {
public void foo() {
for ( int i = 0; i < 10; i++ ) {
bar();
}
}
public void bar() {
// do bar
}
}
# Using collaborator (foo and bar can be tested completely independent of each other)
public class Foo {
private Bar bar;
public void setBar(Bar bar) {
this.bar = bar;
}
public void foo() {
for ( int i = 0; i < 10; i++ ) {
bar.bar();
}
}
}
public class Bar {
public void bar() {
// do bar
}
}
package pkg;
import org.jruby.Main;
public class JRubyRunner {
public static void main(String[] args) throws Exception {
runJRubyScript("ipc.rb", args);
}
public static void runJRubyScript(String name, String... args) {
// modify the args for jruby
String[] args2 = new String[2 + args.length];
if (args.length > 0) {
System.arraycopy(args, 0, args2, 2, args.length);
}
args2[0] = "-e";
args2[1] = "require '" + name + "'";
// execute the ruby script
Main.main(args2);
}
}
Now, for a few subtle points that you may have missed, especially considering the simplicity of the code. For starters, why you may ask, not just pass in the name of the ruby file? Why use the -e option at all? Well, the reason is because the ruby file is located in the jar file so it is not accessible via java.io.File which JRuby uses to load the file. This makes perfect sense. And since it defeats the purpose to move the ruby file outside of the signed jar, we must find another way to get this to work. You could read in the entire contents of the file from the classpath and pass it into the -e option, but this is ugly and extremely prone to error, so we take advantage of an excellent feature of 'require' in JRuby. Require loads its files from the classpath. This is excellent, because it means that if we require just the file we want to run, it will be loaded from the classpath and and subsequent requires will be loaded from the classpath as well.
[Legal disclaimer: This was tested on Mac OS X with Java 1.5, JRuby 1.0 and IntelliJ 6.0.5, but should work on any Windows or *nix based system with IntelliJ 6.0.x and the JRuby 0.1 plugin.]
[Legal disclaimer: The screen shots in these instructions are not actually perfect or exactly what you will see at all stages of the process, however they should contain all the information required.]
- Install Ruby Plugin for IntelliJ Instructions (Leaves this page) [Don't look for a JRuby plugin, install the Ruby plugin.]
- Download and Install JRuby (unzip to the desired installation directory) Instructions (Leaves this page)
-
[UPDATE: I PUT IN A FEATURE REQUEST AND JETBRAINS INCLUDED IT SO NOW THERE IS SUCH A THING AS A JRUBY SDK SO THIS STEP IS NO LONGER REQUIRED! YEAH JETBRAINS!!!!]
Create a Ruby link (*nix) or bat file (Windows) [UPDATE: Creating a bat file named ruby.bat does NOT work. IntelliJ looks for ruby.exe which makes this trick more of a pain... On Windows it is probably simpler to create an External Tool for JRuby right now. That way you can right click on a file and execute it and it doesn't require any fancy hacks. Instructions for creating/configuring the "external tool" are below.] that points to the JRuby executable [The IntelliJ plugin requires the executable file be called "ruby" and not "jruby" so we simply trick it by creating a file that points to the real JRuby executable. Hopefully JetBrains will change this for future releases.]
- *nix soft link: ln -s jruby ruby
-
Create a project with a Ruby module (note: create a Ruby module NOT a JRuby module as you won't find any such thing as a JRuby module. Nor do you need one for that matter, as the Ruby module will do just fine thank you very much. I suppose that JRuby wouldn't be very good if it couldn't just replace Ruby as that is what it is designed to do after all! Well, sort of anyway.)

-
Point IntelliJ to your JRuby SDK


So now you can execute Ruby files using JRuby as your runtime in IntelliJ. But what if you want to call out to some Java code? In JRuby you have to manage the classpath if you want to call out to java classes. You can do this by setting the $CLASSPATH environment variable or by using the $CLASSPATH global variable. (which is only accessible after you have executed the " require 'java' " statement) Unfortunately, IntelliJ does not set either value when including a Java module. To be fair, the latter case wouldn't really be possible because of the sequencing that is required, but hopefully they do add support so that in the future the $CLASSPATH environment variable is set automatically for you so classpath dependencies can be managed by the IDE just like for other projects/modules.
The EASY CASE (Ruby modules only)
-
Create java_cp file and enter classpath values [NOTE: Classpath values must end with a trailing slash due to the implementation of the java module in JRuby.]
-
Include java_cp after java and before including any classes

- Run files by right clicking on the file and choosing Run or by selecting the file and hitting the Run shortcut key sequence.
The HARDER CASE (Ruby modules and Java modules in the same project)
-
Change the ruby project SDK to Java (Otherwise your Ruby module will be fine but your Java modules will not work due to a bug in the Plugin.)
See, I told you, you get an irrelevant, nasty error message!
-
Create a JRuby External Tool (Carefully note the parameters and working directory used. Notice that I made the working directory the lib directory where I put my source file(s). This screen shot is inconsistent with the other screen shots taken because it came from another project, so just take my word for it. :))

- Run your Ruby files by selecting the file and choosing Tools -> JRuby.
So, there currently is not a perfect solution for running JRuby in IntelliJ IDEA, however these few steps should get you up and running in a minimal amount of time. In the simple case there are only really two steps that are required that wouldn't be present if you were just using the Ruby plugin itself: creating the link to the executable file and managing the classpath manually (in this case via an included file jruby_cp).

