jvm language preferences poll results
- Overall results
First off, I'd like to thank everyone who voted on this poll.
With a total of 236 votes, here is the summary of the first two questions:
- Are you currently working with or researching about language alternatives for the JVM? - e.g. JRuby, Scala, Groovy
{% img /assets/images/scala_improvements.png %}
Tooling. The majority of comment urge for better tooling and IDE support. That simple.
- Others
People who chose others mentioned Clojure, Fan and Jython, with a clear advantage for Clojure.
- Disclaimer
This poll has no scientific foundations whatsoever and its sole purpose is to summarize the feelings and personal choices of the people who answered it. If you would like the original spreadsheet with the answers, you can find it here and do your own analyzis.
procs lambdas blocks whats the difference
Do you know?
I didn't. And started to get annoyed by using these terms interchangeably and not really knowing the difference.
There are a few. And they are subtle. I don't think most of us would ever have problems with it but it's the kind of information you'll be glad to know when having those weird behaviors in your code on a Friday at 6:01 pm, just before pushing to production. :)
I guess blocks are the most widely used term in the ruby community and there is little mistake on when to use it:
[1,2,3].each do |x|
puts x*2
end
The code between do and end is a block.
What's important to keep in mind is that Procs behave like blocks whereas lambdas behave like methods. To understand what that means, I highlighted a couple of examples:
- The return keyword
I mentioned Procs behave just like blocks and as such, the return keyword abide to the same rules. This means, for instance, that the latest puts statement on the following code snippet, will never run:
def my_proc(x)
p = Proc.new { puts x*2; return }
p.call
puts "After calling proc" #This never gets called
end
my_proc(10)
>>20
For blocks - and procs-, return means "return from the calling method", my_proc in this case. That's why you don't get to see the output of the puts statement.
On the other hand, in the lambda's example, we get the opposite behavior:
def my_lambda(x)
p = lambda { puts x*2; return }
p.call
puts "After calling proc" #This time, we reach this point
end
my_lambda(10)
>>20
>>After calling proc
Here, return says "return from the enclosing iterator", which, in this case, just returns from the block and continnues the execution of the my_lambda method.
- Argument assignment
On to this second difference, procs and lambdas get more interesting when you can call them with arguments. And that's when another subtle difference between them comes in.
I'll start again with a proc:
p = Proc.new { |x,y| puts x, y}
p.call
>>nil
>>nil
p.call(1)
>>1
>>nil
p.call(1,2)
>>1
>>2
p.call(1,2,3)
>>1
>>2
p.call([1,2])
>>1
>>2
See how procs are flexible? They basically won't complain if you do not provide parameters, provide extra parameters or even send an array as an argument where, as seen in the code above, it unpacks the array and assign its values to the correct variables.
As you're probably guessing, lambdas behave like methods and are much less flexible:
l = lambda { |x,y| puts x, y}
l.call
>>ArgumentError: wrong number of arguments (0 for 2)
l.call(1)
>>ArgumentError: wrong number of arguments (1 for 2)
l.call(1,2)
>>1
>>2
l.call(1,2,3)
>>ArgumentError: wrong number of arguments (3 for 2)
l.call([1,2])
>>ArgumentError: wrong number of arguments (1 for 2)
Ruby 1.9 tip
Despite its name, Kernel.proc returns a lambda in Ruby 1.8. This has been fixed in Ruby 1.9. You actually get a Proc back.
- Reference
The Ruby Programming Language - A must have for any Ruby developer.
jruby on rails and legacy java apps managing dependencies
The motivation for this post came from a couple of messages I've seen on the jruby's google group and because I think it's pretty cool to share how we tackled this problem.
- A little bit of context
We, as a vast amount of people out there, have legacy Java code. A lot. In our case this legacy is pretty much crucial to our business. We can't just trash it and start from scratch. Bad idea.
On the other hand we do have new features to be built on top of it. But we wanted an easier way to develop this new stuff and decided for a JRuby on Rails solution, using it as a front-end to our existing services.
- What we decided to do
Our final rails project would make use of a specially created jar file containing our Java application. This Jar would also contain a public interface of the services we'd have to interact with from rails.
As any Java application, ours depend on a number of external jar files that correspond to the various framewoks we usually have in place. e.g.: Hibernate, Spring, apache-commons ...
Which means we need to make our app's jar and all it's dependencies available in the JRuby classpath in order to use it.
Given we're using warbler to package our application as a war file, we just need to place all jars needed into our rails app's lib folder. Warbler then takes care of copying any jar files located in there into the war.
- The problem
So we needed a smart way to include all these dependencies into the project, and copy/paste isn't an option.
In the Java world we use Maven to manage our projects dependencies - and you should too. Because of that our approach involved turning our rails application into a Maven aware project.
Basically we needed a pom file that would declaratively list our java project as a dependency. From there on, Maven knows what the dependencies are and downloads them to your local repository.
Which leaves us with one more task. We need to put all these dependencies into our lib folder after maven has downloaded them.
Below you'll find the pom.xml file that we use to achieve this with inline comments explaining each bit:
<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>com.company</groupId>
<!-- notice how we specify the packaging to be a war,
that way, maven knows where to copy the jar files -->
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<artifactId>railsApp</artifactId>
<name>railsApp</name>
<dependencies>
<dependency>
<groupId>com.company</groupId>
<artifactId>java-legacy-app</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>railsApp</finalName>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<!-- This tasks only creates a basic structure expected by maven,
so it can do its work -->
<id>create-mock-web-descriptor</id>
<phase>compile</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
mkdir -p src/main/webapp/WEB-INF
touch src/main/webapp/WEB-INF/web.xml
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Now in the package phase we copy the jar files
that maven put into the fake web app to our rails' lib folder -->
<id>copy-needed-jars-into-lib</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -f lib/*.jar
cp target/railsApp/WEB-INF/lib/*.jar lib
rm -rf target/railsApp*
rm -rf src
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<!-- Here we optionally create the final war file containing our rails app using warbler,
doing a small cleanup of the files and folders maven created -->
<id>create-final-war</id>
<phase>package</phase>
<configuration>
<executable>/bin/sh</executable>
<workingDirectory>.</workingDirectory>
<arguments>
<argument>-c</argument>
<argument>
rm -rf *.war tmp/war
jruby -S warble && \
mv *.war target/railsApp.war
</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Now from the command line we can just run mvn package and we’re good to go.
Maven will start to package the application as a war file. Since it’s not a Java application we create the empty web.xml file in the compile phase, to fool maven.
After it has copied all the dependencies into WEB-INF/lib the next packaging goals will make sure we copy them to our rails’ lib folder, also creating the final war file, ready for deployment.
Note that once done, you can use a simple code snippet similar to this one as an initializer and load all dependencies:
Dir.entries("#{RAILS_ROOT}/lib").sort.each do |entry|
if entry =~ /.jar$/
require entry
end
end
Then we can just use script/console, script/server and so on, as we normally would.
Sorry for the long post, I tried to pack in as much as I could and I certainly hope it’s useful to someone. Any doubts, comments and etc… just drop me a line. :)
google io thoughtworks on gae
I've just watched a video from Google IO where Martin Fowler and Rebecca Parsons went through some of the aspects that involves the development of an application for the cloud - focusing on the JVM.
In terms of the Google App Engine, you don't have access to a relational database, thing I found out when I first tried it. Instead you get a Big Table.
Martin put out a good analogy and you can just think of it as a nested hash map. It's certainly a shift on how we think these days, but layers of abstraction like google's DataStore and the Java Persistence API will help in the transition.
Another interesting bit about the presentation was on how concurrency works on GAE.
Essentially, in an standard Java application you have a single memory space where you have at least one running thread. You can create threads on the fly, which will share the same memory space, thus making it easy to share data.
On the app engine, things work differently. What you have are separate memory spaces with a single thread on each one. Any attempt to create a new thread will result in an exception. The solution for sharing information in this case? Use the nested hash map (big table).
Now, whereas you might not be worried about this since your application doesn't span any threads, as well pointed by Martin Fowler, it's the code you don't see that you need to be careful with. Any Java application uses a number of 3rd party libraries that might span out threads of their own, which will result in your application blowing up.
That rang a bell. Again, back when I was trying the app engine, one of the configuration bits shared by Ola Bini looked like this:
config.webxml.jruby.min.runtimes = 1
config.webxml.jruby.max.runtimes = 1
config.webxml.jruby.init.serial = true
I think the properties are pretty much self-explanatory but I didn't quite understand the reason for setting it back then.
If you happen to have bigger values for the number of runtimes you want, you need to set the serial property to true, otherwise JRuby will span several threads to create the runtimes.
This is a really good example of things that might fail whether you're migrating or developing a new app to deploy on the App Engine. Luckily for us, JRuby has a smart and neat way to handle this - the configuration I've just shown, but most of the libraries out there that might rely on threads are not prepared.
Martin and Rebecca's opinion on this is that new releases of these same libraries will start to take it into account, since a bigger adoption of the Cloud seem to be on the way.
Make sure you watch the video. I certainly left a lot of interesting stuff out.
helping the jruby effort debugging the source
Wanna help improve JRuby? Make sure you read this post by Charles Nutter first. There he explains how to run Ruby specs with JRuby.
Start with fixing Ruby specs is a great way to get acquainted with the code. And it’s also a important task in order to make sure JRuby is the most complete and compatible ruby implementation out there.
But before you get your hands dirty, it will be a lot easier if you can actually debug JRuby’s source while fixing any specs - or bugs/features for that matter.
how do you keep yourself focused
This is basically a compilation of a few tools/habits that I use to keep focused and at a high level of productivity when working alone. Works great for me and I hope there are useful tips for you as well.
- Music
- This is one of my favorites. When working alone I hate having noisy people around, which happens quite often if you work in an open office space like me. - It is great for pair programming but I find it inefficient otherwise. Thus, I came up with the term the Heavy Metal effect. Ok, just fit your favorite music genre there but the important thing is that it must act as a barrier to the outside world. It won't work if you put something new and start babbling the lyrics!
- Password Manager
- In my day to day I have a number of web sites open like API documents, programming related groups, email... There are also the ones you open a few times a day like the company bug tracker, review board and etc. I find that having a password manager, in my case LastPass, saves a lot of time. The big advantage of it over similar tools like 1Password is that it works on mac, linux or windows. It's just a firefox plugin.
- Multiple Workspaces
- Probably the most obvious item on this list to developers but I's never too much to reinforce it. Multiple workspaces are great. And they are available in whatever platform you happen to be locked in. In my case, I split my environment in at least 3 workspaces:
-Development - where I keep things like my IDE, Browser and Terminal
-Documentation - where I keep API documents, tutorials and related stuff
-Communication - where I have my email, both personal and business, twitter and etc. This allows me to easily set a time per day to do each of my stuff without having noise from things that aren't important to what I'm focusing in that very moment. - App Launcher
- A must! On Mac I use QuickSilver and on Linux, Gnome Do. I won't say much here. If you don't use some sort of application launcher, do yourself a favor, stop reading and install one. You have no idea of how comfortable and time saver they are.
- Batch tasks
- Maybe this wasn't the best title but I couldn't think of anything better.
As a result of having a communication workspace that I use a few times a day, I find stuff that I'm interested in but don't have the time to dig at the moment. So I need a way to queue that and read later when I'm home. The tools of the trade in this case are Twitter + Evernote.
Evernote is roughly a to-do manager. And since they released their Twitter integration it's been dead easy to queue those things I talked about earlier. Just send a direct message to evernote and the item gets added instantly.
coding dojo 1 the fun begins
Yesterday I organized our first CodingDojo here at the company and I'm glad to say it was a great success!
The problem chosen was the Karate Chop, from Dave Thomas' Code Kata.
As it was also my first time organizing a Dojo, we took some time to get things straight, explain everyone the rules and start coding. Nothing that would compromise the experience, though.
The rules were basically the ones of a RandoriKata and as a mechanism for switching pairs we chose the TimeBox with a limit of 5 minutes.
We came up with 3 different solutions in about 1h 30min. The 1st one looking like crap! :)
Which was actually interesting because the general feeling before we started was that it would be boring, or too easy since "everyone" knows what a binary chop/search is.
Wrong!!! It all changes when you have a time limit and a bunch of people behind you doing funny noises! It's a pressure different from your day to day job. A healthy one in my opinion.
Hearing the feedback afterwards was rewarding. Everyone seemed to have had a lot of fun and can't wait for the next one.
I guess the most important lesson we got from it was to be quiet and not bother the current pair when we do not agree with their idea - not even if we do. This one is very important as it both shows respect and allows you to learn from how your colleagues think.
Next thursday we'll keep going with this one and hopefully finish and pick up the next problem! :)
railswaycon jruby internals by ola bini
As always I expected a good talk from Ola and once more he delivered it. But this one was different. It might have been even boring to some ruby developers since we saw a fair amount of java code in this presentation. Ola gave us a tour through the main classes that make JRuby possible with a single purpose: so we can check out the code and hack ourselves. You can download his slides here.
If you've been following both JRuby and Ola Bini for the past year or so, you've noticed the trend and evolution of this alternative - and so far the most complete one - implementation of the ruby language. Specially at conferences.
Last year at QCon London, Ola was also talking about JRuby. At Euruko '08, in Prague, Charles Nutter also talked about it. RailsConf in Berlin also had its share. What all these talks had in common is that they talked about JRuby from a user/developer point of view. They were selling the solution. Convincing people to use it and presenting successful use cases.
And as the trend goes on, JRuby is now faced as a true alternative - one that we, btw, believe here at the company as we're actively using it - and it seems that now the call is for help. Help to make JRuby an even more complete and overall better ruby implementation. Charles' call for help was a great step. As he states, it's a good way to get your feet wet. I answered the call and am hacking JRuby myself, having already submitted a couple of patches. Perhaps this was the reason for which I enjoyed the talk the most. I was already familiar with some of the structure and classes in JRuby.
There were 2 more talks about JRuby: The Pleasure and Pain of Migrating to jRuby, by Steven Bristol and Integrating Enterprise Java with JRuby and Rails, Michael Johann. Unfortunately only the first one was a real case experience, where Steven walked through the problems he faced integrating JRuby with an existing java project. Interesting insights.
Michael Johann basically presented a short tutorial on how to integrate rails with EJB3 which, albeit interesting, failed to address issues faced on real life projects, like dependency management. Issues which we have already addressed in a very cool way here and I plan to share it soon. Still deciding how though...
rails readable test names run individual tests from the console
As you probably know, since rails 2.1 you can write test methods in the following format:
test "hotel should return its permalink" do
#your test code here
end
Which is great, as the test name becomes much more clear. But you can't simply run this test easily from the command line. You'd have to run something like:
$ ruby your_test_file.rb -n test_hotel_should_return_its_permalink
It annoys me. And it's not practical either to make the test fail just so you can get the test's real name.
I wanted to be able to just copy and paste the readable name in the console and have Test::Unit do the conversion and run it for me, like this:
$ ruby your_test_file.rb -n "hotel should return its permalink"
So I created readable_test_names_runner. It's a tiny rails plugin that adds this feature for you.
Enjoy.
rcov jruby and rcov_plugin
The rcov_plugin project is a rails plugin for rcov that adds some useful rake tasks to your application. And since I'm currently working in a JRuby project it made sense to use this plugin.
The thing is, among other stuff, an rcov report from a JRuby project includes some files that shouldn't be there at all, plus you also need to change the way you call rcov as such. Thus, I thought I'd contribute these changes to the plugin and my pull request was approved this morning - just install the latest version and you should be good to go.
It was useful for us here, hope it might be useful for you too.
Enjoy :)