Monday, July 27, 2009
JRuby's Importance to Ruby, and eRubyCon 2009
Sunday, May 31, 2009
Your JavaOne 2009 Ruby Guide
| S304128 | David Miner, Sun Microsystems; Nicholas Solter, Sun Microsystems | Monday June 01 10:50 AM - 11:40 AM | Esplanade 305 | |
| S307894 | Sun GlassFish™ Portfolio: Where Sun's Application Platform Is Going | Eduardo Pelegri-Llopart, Sun Microsystems, Inc. | Monday June 01 10:50 AM - 11:40 AM | Hall E 135 |
| S304001 | Pragmatic Identity 2.0: Invoking Identity Services with a Simplified REST/ROA Architecture | Pat Patterson, Sun Microsystems, Inc.; Daniel Raskin, Sun Microsystems, Inc.; Ron Ten-Hove, Sun Microsystems, Inc. | Monday June 01 11:50 AM - 12:40 PM | Gateway 102-103 |
| S304141 | Ted Leung, Sun Microsystems, Inc. | Monday June 01 11:50 AM - 12:40 PM | Gateway 104 | |
| S304267 | Charles Nutter, Sun Microsystems, Inc. | Monday June 01 1:40 PM - 2:30 PM | Hall E 134 | |
| S304040 | Dave Johnson, IBM | Monday June 01 4:00 PM - 4:50 PM | Esplanade 300 | |
| S311290 | Arun Gupta, Sun Microsystems, Inc.; Jacob Kessler, Sun Microsystems; Vivek Pandey, Sun Microsystems, Inc.; Nick Sieger, Sun Microsystems, Inc | Tuesday June 02 9:00 AM - 5:00 PM | Breakout Room 7 | |
| S311294 | Tim Bray, Sun Microsystems, Inc.; Chris Kutler, Sun Microsystems, Inc. | Wednesday June 03 1:30 PM - 5:00 PM | Breakout Room 2 |
| Script Bowl 2009: A Scripting Languages Shootout | Panel Session | Roberto Chinnici, Sun Microsystems, Inc.; Thomas Enebo, Sun Microsystems, Inc. ; Rich Hickey, Clojure;Guillaume Laforge, SpringSource; Raghavan Srinivas, Self; Dick Wall , Google; Frank Wierzbicki, Sun Microsystems, Inc. | Tuesday June 02 10:50 AM - 11:50 AM | Gateway 104 | |
| Clojure: Dynamic Functional Programming for the JVM™ Machine | Technical Session | Rich Hickey, Clojure | Tuesday June 02 12:10 PM - 1:10 PM | Hall E 133 | |
| The Feel of Scala | Technical Session | Bill Venners, Artima, Inc. | Tuesday June 02 3:20 PM - 4:20 PM | Gateway 104 | |
| Welcome to Ruby | Technical Session | Yehuda Katz, Engine Yard | Tuesday June 02 4:40 PM - 5:40 PM | Gateway 104 | |
| Toward a Renaissance VM | Technical Session | Brian Goetz, Sun Microsystems, Inc.; John Rose, Sun Microsystems | Tuesday June 02 6:00 PM - 7:00 PM | Hall E 133 | |
| Hacking JRuby | BOF | Ola Bini, ThoughtWorks | Tuesday June 02 8:30 PM - 9:20 PM | Gateway 104 | |
| JRuby Experiences in the Real World | BOF | Logan Barnett, Happy Camper Studios; David Koontz, JumpBox | Tuesday June 02 9:30 PM - 10:20 PM | Gateway 104 | |
| JRuby on Rails in Production: Lessons Learned from Operating a Live, Real-World Site | Technical Session | Nick Sieger, Sun Microsystems, Inc | Wednesday June 03 11:05 AM - 12:05 PM | Gateway 104 | |
| Dynamic Languages Powered by GlassFish™ Application Server v3 | Technical Session | Jacob Kessler, Sun Microsystems; Vivek Pandey, Sun Microsystems, Inc. | Wednesday June 03 11:05 AM - 12:05 PM | Hall E 133 | |
| Comparing Groovy and JRuby | Technical Session | Neal Ford, ThoughtWorks Inc. | Wednesday June 03 2:50 PM - 3:50 PM | Gateway 104 | |
| Performance Comparisons of Dynamic Languages on the Java™ Virtual Machine | BOF | Michael Galpin, eBay | Wednesday June 03 6:45 PM - 7:35 PM | Esplanade 300 | |
| Alternative Languages on the JVM™ Machine | Technical Session | Cliff Click, Azul Systems | Thursday June 04 9:30 AM - 10:30 AM | Gateway 104 | |
| Pragmatic Identity 2.0: Simple, Open, Identity Services Using REST | Technical Session | Pat Patterson, Sun Microsystems, Inc.; Ron Ten-Hove, Sun Microsystems, Inc. | Thursday June 04 10:50 AM - 11:50 AM | Esplanade 307-310 | |
| "Design Patterns" for Dynamic Languages on the JVM™ Machine | Technical Session | Neal Ford, ThoughtWorks Inc. | Thursday June 04 10:50 AM - 11:50 AM | Gateway 104 | |
| Exploiting Concurrency with Dynamic Languages | Technical Session | Tobias Ivarsson, Neo Technology | Thursday June 04 1:30 PM - 2:30 PM | Gateway 104 | |
| Scripting Java™ Technology with JRuby | Technical Session | Thomas Enebo, Sun Microsystems, Inc. ; Charles Nutter, Sun Microsystems, Inc. | Thursday June 04 2:50 PM - 3:50 PM | Gateway 104 | |
| Monkeybars: Tools-Enabled Swing Development with JRuby | Technical Session | Logan Barnett, Happy Camper Studios; David Koontz, JumpBox | Friday June 05 12:10 PM - 1:10 PM | Esplanade 302 |
Thursday, May 14, 2009
BiteScript 0.0.2 Scripting Examples
BiteScript is basically just a simple DSL for generating JVM bytecode. I use it in Duby and now in the "ruby2java" compiler we'll be using to turn Ruby classes into Java classes.
I've blogged about BiteScript here before, but I realized today I never posted any simple "hello world" examples. So here's a few of them, all using the command-line "scripting" mode.
First, the simplest version:
main do
ldc "Hello, world!"
aprintln
returnvoid
end
Obviously this is using a predefined "aprintln" macro, since there's no "aprintln" opcode on the JVM. Here's a longer version that shows how a macro would be defined, and accepts one argument
import java.lang.System
import java.io.PrintStream
macro :aprintln do
getstatic System, :out, PrintStream
swap
invokevirtual PrintStream, println, [Object]
end
macro :aprint do
getstatic System, :out, PrintStream
swap
invokevirtual PrintStream, print, [Object]
end
main do
ldc "Hello, "
aprint
aload 0
aaload 0
aprintln
returnvoid
end
And of course this is just Ruby code, so you can just use Ruby to alter the generation of code:
main do
5.times do
ldc "Wow!"
aprintln
end
returnvoid
end
These "BiteScripts" can all be either run with the "bite" command or compiled with the "bitec" command:
$ bite examples/using_ruby.bs
Wow!
Wow!
Wow!
Wow!
Wow!
$ bitec examples/using_ruby.bs
$ javap -c examples/using_ruby
Compiled from "examples.using_ruby.bs"
public class examples.using_ruby extends java.lang.Object{
public static void main(java.lang.String[]);
Code:
0: ldc #9; //String Wow!
2: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
5: swap
6: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
9: ldc #9; //String Wow!
11: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
14: swap
15: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
18: ldc #9; //String Wow!
20: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
23: swap
24: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
27: ldc #9; //String Wow!
29: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
32: swap
33: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
36: ldc #9; //String Wow!
38: getstatic #15; //Field java/lang/System.out:Ljava/io/PrintStream;
41: swap
42: invokevirtual #21; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
45: return
}
This last example shows the resulting JVM bytecode as well.
Future plans for BiteScript include making it have better error detection (right now it just falls back on the JVM bytecode verifier, which is not the most descriptive thing in the world) and improving the API to more easily handle all the various combinations of class, field, and method modifiers. I'd also like to make it detect if you're doing bad things to the stack to save you the hassle of interpreting verification errors that may not happen until runtime.
Anyway, give it a try and feel free to contribute; the code is all Ruby, wrapping the ASM bytecode library, so anyone that knows Ruby can tweak it. The project page and wiki are hosted at Kenai.com: http://kenai.com/projects/jvmscript
And if you're not up on the JVM or JVM bytecodes, the JVM Specification is an easy-to-read complete reference for code targeting the JVM, and here is my favorite JVM opcode quickref.
Help JRuby by Fixing RubySpecs
You may have noticed we periodically update our RubySpec "stable" revision number, and usually have to file a few bugs. This isn't because we don't want to fix those issues...on the contrary, we would love to fix them. We just don't have enough manpower, and there's usually harder issues we need to tackle first.
But most of the failures are easy to fix, and a lot of JRuby newcomers have gotten their feet wet fixing them. So here's a short guide on how to run the specs and fix them quickly.
1. Get a JRuby working copy and build it
This is as simple as 'git clone git://github.com/jruby/jruby.git', then 'cd jruby' and 'ant'. You'll need Apache Ant 1.7 and Java 5/1.5 or higher (grab "Java SE Development Kit" from the Java SE downloads page.
2. Run the CI spec run
We have a clean spec run that should be clean for you before you start. Just run "ant spec-short" and it will pull the mspec and rubyspec repositories, roll them to the stable versions, and run all known good specs. Now you're ready to investigate specific failures.
3. Run specific spec files with bugs reported
You can look in Jira under the "RubySpec" category, or look under spec/tags/ruby for "tag" files listing failing specs and Jira bug numbers. Once you find something you'd like to investigate, run that spec file using "bin/jruby spec/mspec/bin/mspec <path/to/spec/file>". For example to set the Range#initialize failures I just reported, run "bin/jruby spec/mspec/bin/mspec spec/ruby/core/range/initialize_spec.rb".
Now you can proceed to fixing it.
4. Identify where the problem is.
Most of the core classes are pretty easy to locate. Any classes in the "core" specs will have a Java class named Ruby
5. Create a patch and submit it to the bug
Once you have a working fix, you can go ahead create a patch, either with "git diff > somefile.patch" or by committing it to your local repository and using "git format-patch -1" to create a formatted patch for the topmost commit. Some git-fu may be necessary, so I usually just use "git diff".
That's all there is to it! You'll be a JRuby contributor in no time!
Wednesday, May 13, 2009
fork and exec on the JVM? JRuby to the Rescue!
My first answer was "yes", since there's no direct way to exec a program like vim (which wants a real terminal) and have it work on the JVM. The JVM's process launching gives the newly-spawned processes the child side of piped streams, which you then have to manually pump (which is what we do in JRuby's system, backtick, and exec methods). Under these circumstances, vim may start up, but it's certainly not functional.
But then I got to thinking...if you were doing this in C, you'd fork+exec and all would be happy. But we can't fork+exec on the JVM..OR CAN WE?
As you should know by now, JRuby ships with FFI, a library that allows you to bind any arbitrary C function in Ruby code. So getting fork+exec to work was a simple matter of writing a little Ruby code:
require 'ffi'
module Exec
extend FFI::Library
attach_function :my_exec, :execl, [:string, :string, :varargs], :int
attach_function :fork, [], :int
end
vim1 = '/usr/bin/vim'
vim2 = 'vim'
if Exec.fork == 0
Exec.my_exec vim1, vim2, :pointer, nil
end
Process.waitall
Running that with JRuby (I tried master, David tried 1.3.0RC1, and 1.2.0 works too) brings up a full-screen vim session, just like you'd expect, and it all just works. No other JVM language can do this so quickly and easily.
We'll probably try to generalize this into an optional library JRubyists can load (require 'jruby/real_exec' or similar) and perhaps add fork and exec to jna-posix so that the other JVM languages can have sweet, sweet process launching too.
JRuby rocks.
JRuby Nailgun Support in 1.3.0
- jruby --ng-server starts up a server. You can manage it however you like
- jruby --ng uses the Nailgun client instead of launching a new JVM for the command you run. You'll just need to run make in tool/nailgun to build the ng executable (already built for you on Windows).
Heres a sample session:
~/projects/jruby ➔ cd tool/nailgun/ ; make ; cd -
Building ng client. To build a Windows binary, type 'make ng.exe'
gcc -Wall -pedantic -s -O3 -o ng src/c/ng.c
ld warning: option -s is obsolete and being ignored
/Users/headius/projects/jruby
~/projects/jruby ➔ jruby --ng-server
NGServer started on all interfaces, port 2113.
^Z
[1]+ Stopped jruby --ng-server
~/projects/jruby ➔ bg
[1]+ jruby --ng-server &
~/projects/jruby ➔ jruby --ng -e "puts 1"
1
~/projects/jruby ➔ time jruby -e "puts 1"
1
real 0m0.609s
user 0m0.482s
sys 0m0.119s
~/projects/jruby ➔ time jruby --ng -e "puts 1"
1
real 0m0.073s
user 0m0.010s
sys 0m0.018s
Update: For those not familiar, "NailGun is a client, protocol, and server for running Java programs from the command line without incurring the JVM startup overhead. Programs run in the server (implemented in java), triggered by the client (written in C), which handles all I/O."
Wednesday, April 29, 2009
Stand and Be Counted
Unlike Nick, I too often have used this blog as a soapbox. And too often I've ground my personal axe against projects that may or may not have deserved it. I'm human, I'm passionate and proud of my work, and I'm defensive of what we've accomplished, so I don't think this is surprising. I also see the same passion and pride in the Ruby community at large, and it's why I'm much more interested in attending Ruby conferences than Java conferences, where many attendees just seem to be going through the motions. And I know I've crossed a line at times, making or taking things too personal, and hopefully I've apologized or corrected myself whenever that's happened. If not, mea culpa.
But there's a disturbing trend in the Ruby community I haven't had to deal with since high school: in preference to open inclusion, more and more Rubyists seem to choose exclusivity.
This recent firestorm has continued in large part, I believe, because of the poor initial response by folks involved. Rather than recognize that there are people with different views, taking offense at different ideas and images, some decided to say "fuck you, this is who I am" and further alienate those people. I certainly don't expect we as passionate individuals won't commit occasional faux pas, especially when trying to be funny or provocative and especially when coming from different backgrounds that may be more or less accepting of certain behaviors. But to claim no responsibility for an obvious mistake, indeed to claim it's somehow the fault of the offended, or American sensibility, or political correctness...well that's just sophomoric.
I think to some extent we can understand (but not excuse) such behavior by realizing that the Ruby (or perhaps the Rails) community is largely a very *young* community. That's a large part of why this community is so passionate, why they're so committed to their ideals, why they're so opinionated, why they're so much more fun to hang out with than many 30-year programmers from other communities who've had the life sucked out of them. It's also a reason so many in the Ruby (or perhaps the Rails) community seem to act like they're in high school, forming cliques, sitting at their own tables, snubbing the new kids or the weird kids or anyone they perceive as "trying to be cool."
Have you been invited to any exclusive Ruby communities? I've been invited to a couple, and without exception I've found the idea offensive every time. In some cities, there are now multiple tiers of Ruby group: one for the proles, where anyone is welcome and everyone is either new to Ruby, a little weird, or both; and then perhaps one or two levels of more "exclusive" groups, usually more "advanced" and sometimes invite-only but generally exclusionary in some way.
There's also a technical "coolness" exclusivity many projects have had to cope with. Folks working on JRuby and IronRuby, for example, have had to deal with perceptions that they're either less "cool" because of their platform of choice or at least somehow less "Ruby" because they're not following the same golden path everyone else follows. Or perhaps their employers are out to take over Ruby, or they're going to infect Ruby with a bunch more "new" people who don't "get it". All the while the folks that use and work on these projects are working just as hard as anyone else to bring Ruby to the world, staying true to what makes Ruby special, and largely going against the grain in their original communities as well. Being snubbed, mocked, or attacked is often their reward.
You start to see a pattern here, yes?
So let's spell it out. I like the Ruby community because it's filled with people who love playing with new technology, without biases and prejudices getting in the way. My closest friends in the community are people like me, who find it repugnant that being opinionated has been too often equated with being rude and boorish, exclusionary and sophomoric, or simply mean. We are all here because of our love of technology, all here because we didn't feel like we fit in other places that weren't so passionate about beautiful code and fresh ideas. We are all here because we don't care if you're male or female, religious or irreligious, young or old, experienced or inexperienced, beautiful or plain, conservative or liberal, tall or short, fat or thin, foreign or domestic, gay or straight, black or white, or any grey areas in-between. We are all here because we love that more and more people like us join the community every day...the same people some of us immediately judge and box into their own subcool subgroups.
I don't want to join your damn clique. I don't think it's ok to set people aside or treat them like dirt because they don't believe what you believe or because they have their own way of thinking and acting or because they're not as worldly and mature and oh-so-smug as you are. I don't believe in "rock stars" and I don't believe that dubious title gives anyone the right to be an asshole to others or to have free reign to act any way they choose. I don't care what kind of car you drive, what house you live in, or what clothes you wear...and I sure as hell don't care how many people follow you on Twitter.
What I do care about is whether you're interested in sitting down and hacking out some code, looking at new projects with an open mind, helping someone new (maybe me) improve their skills, being part of something larger than yourself. If you promise not to treat me like a weirdo or a rock star, I promise to talk openly about your ideas, to show you the heart and soul of my code, and to freely share my thoughts...no matter who you are. I hope you'll attend my presentations and/or try out my projects, and in exchange I'll try to do the same the same for you. I hope you'll walk up to me at conferences and tell me about whatever "crazy" or "stupid" idea you have, and I guarantee to listen since it's probably not as crazy or stupid as you think. And I expect you to do the same for everyone else in the community and not treat me or anyone else any differently.
Now, let's move forward and get back to hacking and having fun!