>>We have our Ruby series continuing. We
had Mats last week and now, we go over to the Java side of the Ruby house. And Mats
kind of said a little bit in his two–last time here how it’s a bit of a bittersweet
taste with JRuby and being a little bit faster than his interpreter. And so now, we get to
hear from one of the guys that made a big difference to give us those performance improvements
so let’s give a hand to Ola.>>BINI: Thank you. It’s wonderful to be here.
I actually haven’t been [INDISTINCT] in this area before. So coming down to Google and
see all the stuff and feel that the vibe here is–it’s nice. So, yes, JRuby what, why and
how? It’s actually–I mean, I have lots of slides but I’m going to keep it kind of open
so if anyone has any questions and if you want me to expand more on, just feel free
to say so and I’m sure we can accommodate that. I am from Sweden. So if you’re wondering
where my accent is from that is it. I am a programming language nerd. I’m not an educated
one. I’m just dabbling in them. I’ve been a JRuby core developer–one of the JRuby core
developers for two years. I spent two and half years trying to make JRuby one of the
best Ruby implementation available. I happen to be the author of Practical JRuby on Rails
too. It’s the only book on JRuby right now. So if you’re interested in JRuby and JRuby
on Rails, yeah, that’s the choice you have. I’m not endorsing it. I’m just saying. So,
I’m going to talk a little bit about Java versus Ruby first of all. I am sure all of
you are kind of familiar with a little bit–actually I’m not sure. Ruby, how many people are familiar
with Ruby? Okay. So, this is good. So, this is not going not come as a surprise. I’m going
to focus on a few of the aspects that make Ruby a different language and different and
more useful for other problem domains that may or–where Java might not actually be so
well suited. I’m going to talk about JRuby obviously, how to get started. Some problems
with Ruby that actually JRuby solves and I’m going to take a look at the implementation
and that’s when the real language geekery comes in and I’m going to end up looking at
some cool things, possibly some Rails, possibly not some Rails depending on people being tired
of hearing about Rails all the time. I have some plenty of room for Q and A. So, let’s
talk with my first demonstration and this is actually–I usually do this live coding
but I’m not going to do it this time so you’ll have to bear with me having a pre-canned example
for this one. So, I have this code here. It’s about the screen full of really readable code,
right? So, I’m wondering what’s the actual purpose of this code? Where is the business
logic? I can describe what this code does in less characters than I actually need to
get it to compile in Java. I can actually describe it thus saying create a list of these
names. I want to sort it by length and then I want to print them out separated by a coma.
I don’t know how many syllables that is but I’m sure I’m around the main statement if
I–if I can not do the count. So, watch me just for comparison, okay not–more angle.
So, this is the Ruby equivalent. Now, here we’re actually talking about the same length
of code for what I said. There are lots of things that we tell the Java compiler that
we shouldn’t really tell it. We tell it for once. We tell it two times that we need to
do as list of string. That is kind of annoying. Here, we don’t really care what the list is
of because we know that we’re just sending in strings. We’re sorting by length and we’re
joining them by coma and now we’re printing them. If you have Ruby 19 or the active support
extension so you can actually just say sort by length and we don’t need to even have this
implicit–this variable called name here to make that example. So, that was just a very
short comparison and I’m going to come back to that later on. So the thing is there are
few things that are extremely verbose in Java. The base language is verbose and you don’t
really have that many things that can help you to abstract things. So Ruby, you have
Blocks. Blocks help you to abstract things quite heavily actually because you have real
closures. You have modules that connect as mix ins, that means that you can actually
share behavior–shared behavior that doesn’t really depend on implementation. You can still
have a shared implementation for stuff that just depend on something–something. It doesn’t
really matter. And then you have the Metaprogramming–what? Oh, okay. Metaprogramming which is really
useful if you really want to compress things for real. I happened to be one of those lisp
guys who prefer Comma lisp but real sell macro so compressibility and readability doesn’t
really have to go in opposite directions. I believe that with Ruby’s metaprogram facilities,
you can create small languages that are extremely readable but still expresses exactly the business
intent of your code and nothing else. And it can actually expand into something that
is a really good implementation that gives you all the secondary things that you actually
need from a business implementation. There are–at the end of the day, there are more
means of abstraction and that is really what matters. The more ways you can abstract something,
the more choices you have to make your implementation readable, understandable, maintainable. So,
I mentioned verbosity that is one of the things. Ruby also is not malleable language–no, sorry.
Java is not a malleable language. You can’t really change the way anything works. Just
take a typical example, Ruby you can leave off parenthesis on a metacode. That means,
that you can choose which looks greater–which looks better. If you want do it DSL, you usually
end up not having parenthesis. So you can do something that is readable in a different
way. Also the malleability of the language makes it easier to have a quick turn around.
You have an agile way of working where you can actually change the application in real
time. While the customer’s sitting by side you can change it and you can accomplish things
without actually having to do a long compile cycle and so on. Of course you have all that
stuff with the test cycle in Ruby too, but to actually just spike functionality, you
can do it faster. And DSLs–well, you can say lots about DSLs. They are one of the hype
words right now, I would say and Ruby is better at it than Java. I would say it would be very
hard to write a domain specific language inside of Java. You would actually have to just go
outside and use a parse and rate or something like that. Ruby is also full of innovation
right now. I point at Rails as an example of the innovation that can happen if a language
frees you to actually don’t care about things that doesn’t matter when you’re doing something.
When you want to do–when you want to do exploratory programming for example. You don’t really
care about the types of your list. You just want to have a list of something that you
can shove things in, take things out of, you can change it in some way, etcetera. And that
kind of exploratory programming ends up being really hard in Java. Of course you can start
out in Ruby and then transform into Java but that kind of programming is really–when you
have invested lots of amount of time in exploring an implementation with Ruby, most programs
doesn’t really feel comfortable translating this into Java and seeing the source code
explode with typed tags. So it doesn’t–they’re not happening that much. But we’re seeing
that Rails for example has a real effect on programming language environments outside
of the Ruby world. We’re seeing that Java frameworks is actually taking up the learnings
from Rails and putting them into the Java world and this is happening in other areas
too. You have stuff like testing for example, where our spec is leading the way of behavior
driven development. Now, this started off with JBehave and–which quickly got turned
into RBehave and RBehave got munched into RSpec and this is were all the new stuff is
actually happening. So it’s–to me, it’s a matter of language power. In some situations
Java makes sense. In some other situations Ruby makes sense and the important thing is
to actually choose which is which. So JRuby is an implementation of the Ruby language.
It runs on top of the JVM. It’s one of the five compatible in the current trunk. We have
one now released that we are maintaining. That is 1.4 compatible. It can also use Retroweaver
to get 1.4 compatibility of JRuby. It’s fully open-sourced, you can choose which slices
you want to use. You can use JPL, CPL and yes, some air via [INDISTINCT] license so
it’s kind of free. One of the things that I end up saying every time I stand here talking
about JRuby is that, JRuby can be a little bit boring because it’s really like Ruby.
It works exactly like Ruby. It is the Ruby language. There is no difference. Well, there’s
a slight difference but differences are extremely small compared to the fact that basically
the whole language is there. It’s compatible with Ruby 196. We count compatibility basically
by doing lots of testing against different testing frameworks and specifications that
exist and we also–basically just run application frameworks. So, when Rails and RSpec and a
few other of the most complicated Ruby systems out there actually works flawlessly. That
means that we are compatible. Our current release is one of one RC2. We are planning
on having an RC3 out this week or this weekend hopefully if I get the time to pitch in, it
might actually happen. We do have the 1.0 branch I mentioned. It’s kind of falling behind
though because we’re can’t really back porch some of the–some of the more cool stuff we’ve
been adding in the 1.1 branch. So, we are probably going to continue doing bug fixes
but if you want to be actually getting the full Ruby treatment, JRuby 101 is going to
be that. The product is old. It actually started in 2001 and we’ve had lots of different developers.
The current, oldest, longest developer is Tom Enebo. He’s been around in the project
for four years. I joined two and a half years ago and well, that is really it. We’ve had
lots of people just going into the community and getting–going out of it. Right now we
have eight core developers. Forty-fifty contributors something, we have spikes so, every time we
do a release we get a new batch of contributors that kind of get the numbers up. And we have–actually
had some interesting development happening, some outstanding contributions. Marcin one
of our–one of our core developers, this fall he actually ported to full Oniguruma regular
expression engine. And Oniguruma is the expression engine that lies behind regular expressions
in Ruby 1.9. It’s very large. I think it’s the C implementation is around 120,000 lines
of C code and this is a full Java porch. It–just as a side effect, it actually ends up being
the fastest regular expression engine available on the java platform right now. So, things
like this kind of end up happening as a side result of doing a good Ruby implementation.
It’s really–really, really, really simple to get started with JRuby. If you want to
try it out, you down load the distribution. You–at that point you actually get the Ruby
standard library. You have the RubyGems. You get Drake, you unpack it and you add the binaries
to the path. The [INDISTINCT] path and then you can just go on using it, using the JRuby
to command. You can use it in several different directories as long you have one economical
JRuby command, that’s fine. You can install gems, either you can do a gem install if you
don’t have regular Ruby installed and you can do JRuby-S gem install. This will use
the gem that’s comes with JRuby and that’s really it for getting started. And this is
just an example of how easy it actually is with Java 6 to call out the Ruby code from
Java. You create a new script on your manager, you get that engine unnamed and then you evaluate
the code. And what you get back here is actually the result. You will–what you will get back
here is an unwrapped mail object because that’s actually rich on snail. So it won’t get any
interesting from this evaluation but you can imagine actually doing some–say for example
you can imagine creating an interface implementation implemented in Ruby that you return from this
evaluation and using your quote. In general, using JRuby is easier if you let the Ruby
layer drive the Java layer. You can do it this way but the easiest way is actually running
it from the JRuby side. So, a small demonstration of interactive Ruby, so how many–yes, of
course. All of the people who actually put up their hands saying they know Ruby have
used interactive Ruby, right? So I’m going to show you the JRuby flavor of interactive
Ruby. So, I’m just resize this a little bit because I happen to know that this going to
be–so that’s–is this readable? Okay good. So, let’s see, sometimes this command takes
some age to start because the Java loading of all this stuff, colluding on the Mac has
the tendency to be a little bit slower than it should be. It’s just the first time though.
So, this is IRB running JRuby so it’s just one of one–print, hello Google, all the regular
stuff that you kind of expect would work works and–but there’s also this–oops. There’s
also this that I can type wrong, require Java. Now, requiring Java gives you access to the
Java component of the system so I can do the Java line systems that, out.print run “Hello
Google” and this will work as expected. So, this is the way it can actually work with
these classes. Printing out stuff might not be useful. I keep around–I keep around this
console because I find myself a little bit frustrated by the Java docs in some of the
security APIs for example. So I keep IRB around open so I can try things out. So I can–for
example, I can get all the algorithms since the available algorithms is different on all
the systems in Java, this will always return different results. So in this case we get
a few different algorithms for message digest. Now, when I get back is a Java object. This
is in Java array. If you actually look at implementation of Java secured the security.
You’ll see that this method actually returns primitive string array but I can use something
like Brick to just find all the show implementations. So, in this case I’m running something that
is typically Ruby. The Grep command on a Java array, and we have all these kinds of integrations
that help us do that stuff. So I can manipulate data from Java as if it was Ruby data. I can
create a new and–you have a Java.util.hashmap.new, if I want to. I can say, okay, at the index,
“Hello, I want to have world there,” okay so age. You can still see in this funky syntax
that this is still a Java object. This is Java.util.Hashmap. So all of that stuff kind
of works and we’ve added lots of extensions to the Java integration to make it really,
really obvious how you can work with stuff. And in many cases if you used Ruby, it just
works. If you use the Java you will find more and more shortcuts that kind of makes sense.
So, I have a tendency to–just as a typical example of what you can do with a dynamic
language that allows you to manipulate stuff at runtime, this means that I can create a
new swing frame for example. And I can set the size to 400×400 and I can show that–show
that and I got a frame that I started from and an erection–interaction prompt, but that’s
not really–I can actually work with this one too so I can create a new button. Java
X.swing.J button, right? Hello–well, I need to come up with new examples. Okay, so I have
a button that I added dynamically. Okay, so that’s cool. Next step would be to actually
do something. So, in this case I want to add an action listener. So, let’s see if I typed
everything right. Okay. So, the button text changed. The button pressed. So, I’m now executing
Ruby code from a callback from–right–right inside of swing and this just works. Notice
that I actually didn’t implement any interface to do this because the actual listener interface
has one method. We can actually coerce a block to just do the same thing as would have happened.
It kind of understands that the interface needs to be implemented and puts the block
implementation as the action of that interface. There are a few shortcuts like this but if
you wanted to you could have just implemented, interface create a new Ruby class and create
an instance of that, works too. So, this is the gist of the Java integration from JRuby.
It kind of–the focus of it is that it should just work. One of the things that I really
like about Ruby is the whole principle of least surprised and this is really true for
the Java integration stuff. If I want–I want to be able to just assume that stuff works
as I expect them to do and that’s kind of the guiding principle we’re using. Yes.
>>So that coercion is [INDISTINCT] it’s creating interface behind the scenes, can you still
do the trick where you just–say define a function that is the action method performed
method and then pass that into the add action listener that records that as well? So that
you had an interface that had multiple methods on it, you could still just create anonymous
functions or?>>BINI: So that’s an interesting question.
So, what I–let’s just–sorry?>>Not to highjack anything [INDISTINCT]
>>BINI: This is exactly what I told you to do, right? In the beginning of the talk so,
let’s see. So, in this case–I’m not going to actually–well, I’m going to require Java.
So, the way I would do this, I would do it like as say, button action and I would do
that to be a proc who takes an argument. And then later on if we assumed that I still had
the B–the B button still available, I could do a B.add action listener, button action.
Now, if you know Ruby, then you know that the ampersand is actually coercion to a block,
actually it coerces a proc into a block. So, I’m doing exactly the same thing as I did
the last time as yesterday, kind of get surrounded by saving the block inside of a variable.
So, this is the way–one of the ways that could do it, and another way I could do it
is actually I could do Java.A with WT.event.action listener.impl. This is something we’ve added
which will create an anonymous implementation of the interface. This anonymous implementation
is kind of creative with using dynamic proxies and the way it will work is you can use it
on either interfaces with just one method like action listener in that case–actually
it’s no difference. You can use it on any interface and you’ll get back an anonymous
class. Every method on that interface will invoke this block. The name of the method
invoked will be the first parameter which is the underscore here because I don’t care
about that since I want to do the same thing on all of them. So, this is the equivalent
of an anonymous implementation except that this is actually implemented in Ruby.
>>So, the question I was actually asking you is more about–so if you define that function
in the scripting environment then the current, you know, IRB object list gets that method
so via duck typing–if you past this as the current interpreter like main object into
the method, we’ll be able to duck type the method signature and call it for any given
interface implementation.>>BINI: No. The coercion actually happens
just for blocks so you would have to–what you could do–of course you could use Ruby
so you can always do–say if I wanted, say P the–or pots to be called. I could do method
pots and I think I can do two proc on that one, right? Yes. So, I can call method pokes
and two proc and then I could do–actually, yes. So, I could just do [INDISTINCT] B.add
action listener and I could do the ampersand and then I could skip to two proc. So this
would do the same thing. This would actually call puts and print out the argument. Is that
what you were asking or did I misunderstand again? Okay. It’s all good. Okay. So, let’s
see. Where was it? Okay. So, that is kind of the interaction. They’re–they have–as
I said, the guiding lines is that to Java interaction should just work. Now, this means
that the Java interaction–I just showed you swing classes, I showed you collection classes
and stuff like that. It also means that more complicated stuff works. You can do this with
EGBs if you like that kind of thing. You can do it with JMX. You can use it with of–you
know, I don’t want to get into all those TOAs but, you know, you can–if you can imagine
in a Java TOA, you can use this wedge, it works. So, let’s get back to some of the issues
that we’re actually trying to solve. I mean, the–these were not rationale for creating
[INDISTINCT] from the beginning but this–they are kind of the guiding lines for us to continue
working on JRuby because we believe that we actually solve problems that had not been
solved in Ruby 1.8 and Ruby 1.9 and we want to solve these problems because they are kind
of in the way of Ruby actually getting an attraction. Ruby has some traction right now
but we–at least in [INDISTINCT] believe that Ruby may–it could get so much more attraction
than it does right now. And these things are kind of in the way. So, we have threading.
Ruby 1.8 has green threads, that means that they don’t scale. That means that when I run
Ruby on this lovely machine which has got two cores, I don’t really get my full money’s
worth. C libraries can’t–won’t yield and the schedule there is kind of–kind of basic.
In Ruby 1.9, this is getting fixed by using native threads but they still had the global
interpreter lock which means that no native threads will run at the same time. So, I will
actually not have a solution for this and as far as I understand, the global interpreter
lock is not going to go away because so many extensions rely on the way the threading features
work. There is no synchronization, no mutics as in any of the Ruby C code or the C extension
code. And there are just too many extensions to handle this correctly. We kind of fake
this issue out by not caring because we are using Java threads as Ruby threads. That means
that they are native. They are parallel and since all of the code in JRuby is Java, it
means that we get the same threading semantics for the Ruby implementations as you would
get from Java. So, extensions need to–okay, so if you write an extension, yeah, you need
to synchronize the way you do in a Java program. And everyone is kind of used to that when
they write Java codes. So, we don’t really need to do anything specific to handle the
problem. Unicode gets–actually it gets a solution in 1.9. It’s kind of the Full Monty
solution meaning that not necessarily only unicodes or UTF8, but you actually get all
the–in the encoding you can imagine–you can actually use Ruby 1.9 and all different
strings can have their own encoding and they can kind of float around in the same area
and have fun together. That is very nice. It’s kind of hippy. We don’t want to go that
far so we used Java’s unicode. So, once again–once again we full back to the Java platform. It’s
just stuff that we get for free for being on the Java platform. I’m going to talk about
performance a little bit more later ,but suffice to say right now, Ruby 1.8 can–their motto
is that Ruby 1.8 is fast enough but in retune–in routine it only finishes last and there is
no real plans to improve this. The improvements in Ruby 1.9 is happening. I saw the talk that
Mats gave last week. If I remember correctly he said there were improvements and several
benchmarks from five to a 100 times in performance but the general performance improvements for
applications were more like 1.5 times. So, this is 1.5 times for a new virtual machine
and there are things that aren’t really solved by the 1.9 release. For example you only have
the implicit ahead of time completion that happens inside of the engine. There’s no way
of doing ahead of time compilation done about the byte codes. There is no just in time compile
and so on. So, I’ll go back to [INDISTINCT] or to this–to this part later. Memory management.
I actually–I did a talk at Powerset yesterday. Powerset is doing some really cool stuff and
my question, “What’s your main problem with Ruby?” And their main problem was memory because
the interpreter kind of leaks. Its got a very, very simple garbage collector and it’s not
really–it’s not really fit for using large scale environments, right–right now because
the design is simple and it works for simple apps but, ugh, and Ruby 1.9 is not going to
change this. It’s actually going to worsen the situation because improved performance
means more garbage which means that the garbage collection problem is just going to explode
in our faces when we try to use it. And yeah. This–this question–this answer is actually
getting a little bit old because we just used Java’s garbage collector. We have a few hundred
options that can tune it. We have four or five different algorithms for the garbage
collector in current Java release and all of that works happily with our code. C is
a lovely language for writing operating systems. It doesn’t really scale and it’s got some
problems that makes it unsuited to make extended–create extensions. In the Ruby implementation, you’ll
see lots code devoted to spreading and garbage collection issues and so on. And in JRuby
well, the extensions are Java extensions so once again, no problems like that no explicit
garbage collecting handling. The only creating handling that is expressed is the real synchronization
we need to do. Oh, and then we have the politics one. You want me to switch to watch? This
is going to improve later on in the game hopefully with time. But that’s not really quick enough
to actually get real traction. There are also lots of Java applications in the world and
so many Java frameworks. It’s kind of like–I would say that the Java libraries are definitely
approaching Perl Cpanning completeness and comprehensiveness. And I would say that they
are much better in stability and quality than Perl Cpanns and just straight over the board.
So, which is why we’re one of the reasons we’re running on top of the Java implementation.
Credibility by association by just running on top of Java, it makes it easier for us.
And we find that the regular Ruby implementation actually have an easier situation because
we exist. Now, companies that wouldn’t use Ruby are actually switching to the regular
Ruby interpreter because they know they fall back on JRuby and proven Java technology if
they need to. So, it’s kind of a false thing. It–it doesn’t really solve anything for real
but this is more about perception and it’s actually funny. We have some real stories
about where this really helps us. We did some work at a large financial institution and
most of the people really, really wanted to–really wanted to have JRuby there. They really want
to have a real Ruby on Rails. I mean there were developers and they saw the benefits
of using rails in their environment and they couldn’t because their management didn’t really
allow them to use that language. They were based on Java. So what actually ended up happening
was that they did it in JRuby on Rails. They gave it to the IS department, they said, “Okay.
So here, this is our application. It’s this really large cool Java application? It runs
on application servers and have all these cool Java features and so on. And oh, we this
long continuation file with it.” Which is one way of doing it. It worked in the situation
and the management is happy. So–then we have the performance. Performance is usually–well,
false enough is good. That’s a good answer in many situations because performance isn’t
really all that important in most cases but at the end of the day you will end up in a
situation where sometimes it actually is important. So, our general numbers right now, JRuby 1.0
in June was actually two times slower than Ruby 1.8.6. The 1.1 beta one, that was about
JavaPolis time December. That was two times faster and current trunk is about five times
faster. We are talking about–we are actually competing against Ruby 1.9 instead of Ruby
1.8 in performance right now. And we’re doing this with full compatibility of the Ruby 1.8
language. Ruby 1.9, one of the reasons Ruby 1.9 is actually faster from any case is for
many of the benchmark, it is because they have removed features that were hard to optimize.
So, right now we’re actually going to stop working on performance and concentrate on
other stuff for a while. When we get back to performance we are going to target Java
performance. We want to have equivalent Java performance for operations that are logically
the same. I’m not sure we’re going to get that close to Java performance but we should
get in at least the magnitude. One of the questions people always ask is about IDE support
and these are the IDEs that I know about right now. NetBeans–NetBeans Ruby IDE, Eclipse
RDT, RadRails, Aptana, DLTK, 3rd rail, IntelliJ, Jedit, all of these support Ruby. And those
IDE–those are the ones that you can count as IDEs. I count eMax, VI and Textmate as
IDEs in this manner because that’s not what people really want to know when you ask about
this. I happen to use eMax only but that’s me. IntelliJ is extremely interesting actually
because they have specific JRuby support, not only Ruby support but they had JRuby support
so when you refactor something, when you change the name of a Java class or a Java method,
IntelliJ will actually find your Ruby code that uses that Java class and refactor at
that point too and back and forth like that, which is really cool. Overall the regular
Ruby refactorings and NetBeans seems to be really going well too, according to people
who use them. Yes. All of these actually use the JRuby parser because there is no other
complete parser around. And no one want to use the C parser from a Java program, right?
So it’s one of those nice side effects of doing the implementation. People can end up
actually having a real Ruby parser that I can use, that I can integrate in our Java
ecosystems without showing out to another program. So, the parser, right, this is the
geek part of the presentation. The implementation–if you’re interested in stuff like this, we have
a hand written lexer. It’s kind of ported directly from Ruby. JRuby started out as being
a line by line by port from the regular Ruby interpreter in 2001. The Lexer is probably
is probably the part of JRuby that has changed the least since then. Well, I do say many
changes is done but it–many less changes than we have done to the rest of the code
base. We haven’t really refactored this part yet. We would love to be able to switch to
ANTLR and there are some people getting really close with ANTLR Ruby grammars. They aren’t
close enough and the problem right now is that the old ANTLR grammars we have looked
at happened to be more than twice as slow as our parser and tent. So, I don’t why that
is and from the maintainability perspective, this is really–ugh, I don’t want to touch
that and–I mean our–right now, our parser–actually so–we have a parser generator that is a Yak
based. It’s a–it’s an old Java program called J. It’s Jack–bison based it’s kind of a pain.
The AST is quite similar to MRI. We have kind of changed a few things that were implementation
dependent and there to make sense. We have lots of core classes and most of the map is
straight down from Java classes through Ruby classes, string is Ruby string. Array is Ruby
Array, and we use sanitations to point out this. It’s kind of interesting if you look
at this because this stuff is things that you need to know about the Ruby method from
the implementation perspective. This is all we really need to know. This information is
spread out all over the MRI implementation. In most cases it’s not even verbalized. It’s
just a side effect of how the interpreter work but we have actually put them here so
we can now allow the compiler and the interpreter to use this information. For example we have
the framing and scoping which we in many cases don’t need. So, when we don’t need it, we
can optimize away from that. If we don’t need frame and scope information, we can omit the
whole stack frame and we can just store local variables in local java variables for example.
So, that is kind of how our source code looks. We have lots of implementations and we have
an annotation saying, “JRuby method, we are looking at adding a few annotations for documentations
and other purposes.” But those refactorings kind of go–get a little left behind after
actual implementation of features. The interpreter is really easy. It’s a switch based AST walker,
it recurses. Most of the code actually stuffs out interpreter except for command line scripts
that are compiled immediately. It’s quite an easy code actually. If you want to learn,
if you want to understand what Ruby does, what happens under the cover of a Ruby implementation,
if you–if you don’t know exactly what happens when a Singleton class is created and–or
what happens when you’re used to double left–the double angled bracket syntax to get to the
Singleton class or something like that, I would say that the absolute best solution
to J would be to look at the JRuby interpreter because that is straightforward Java code.
MRI is fine for looking at the C code. Rabinya is just going to be really lovely as soon
as all of the core is there in Ruby code. But right now JRuby’s interpreter is the only
part that is really readable in my implementation–in my interpretation at least. The same is not
true about the compiler. The–this is kind of a mess actually. It’s a mess that is kind
of necessary, it’s a–Ruby is a complex language parse and it’s even more complex to actually
compile down to Java byte codes to get equivalent actions. We–in one though, we have an–a
Just-In-Time compiler, it was not really full-scaled; it was 25% finished or something like that.
Current trunk has got a full Ruby compiler from N to M. We can compile any instructions
from Ruby. And the command in itself is just an AST walker. It emits a code structure.
And we don’t have a bytecode emitter that actually generates Java classes and methods
and they are real Java light code. If you compile in Ahead-of-Time mode, you will have
a mapping from .Ruby files to .class files. And they’re not going to be real Java classes
because a Ruby file doesn’t really match to a real Java class. So, it’s more of a collection
of methods, it’s a bag of methods so to speak. But we do have a main method for command lined
execution. In Just-in-Time mode we need to actually create one in memory class for each
separate method we are compiling. There’s no other way of doing it really. So, these
are few of the compilation optimizations we can do to actually get some really good performance.
We pre-allocate cached Ruby literals. We use Java for every bytecode to improve the local
flow control in many cases. I mean, not many people know that if you use an explicit return
in Ruby code, it will actually be slower in using the explicit–the implicit return at
the end of file. That doesn’t happen in JRuby because we use the same operation at both
times. We tried to use Java local variables because the performance of these are really,
really good. But we can only do it when we don’t have any closures that are going to
be used in other places. So, eval and binding and stuff like that just kills performance.
And it’s no–there is really no way around that. But in most cases, in most code you
don’t need that stuff. So, your performance is good because we can optimize that stuff.
We use right now monomorphic inline Meta cache. We are looking at possibly implementing Epic.
I’m not sure if that’s going to be happen for 101, but if we do, that’s going to improve
performance even more. So, just to give you a small example of the kind of performance
we’re talking about. Let’s see. So, I have–we kind of–try to have a really good test switch.
So, let’s see. We have lots of benchmarks here. One of the more interesting one is actually
Meta dispatch because Meta dispatchers are the core of the whole environment. So, let’s
see where Ruby 1.9 is with Meta dispatch. So, let’s see if this takes an argument. Oh,
it doesn’t, okay. So, this is–these are a few different things. We have a control first,
that one was really slow, okay. Interesting. I’ll tell–you know what? I’ll let this run
in the background while waiting effects for representation. So, remind me, we are having
a benchmark running. In the meantime, I can continue talking about some things about the
implementation. POSIX has been a problem for a long time for us because Java doesn’t really
support all the stuff you can do in a POSIX system. So, in many cases, normal Ruby things
that we expect, doesn’t really exist in JRuby. Native extensions are not supported and–well,
interaction with C is kind of painful overall–all in all. Now, we find a library called JNA,
Javan–Java Native Access, it’s kind of–it’s kind of like DL to do dynamic loading. And
the main thing about it is that we don’t need to compile stuff for ourselves. We don’t need
to write C code to interact with this stuff. We can just write the stubs in Java and we
can call C method–C methods. So, we have actually implemented quite a lot of Posix
compatibility like this. And we are also thinking about doing this for native extensions, for
the most important ones. I’m not sure if we’re going to do that. But JNA actually allows
us to do lots of stuff. Some interesting stuff like Unix domain sockets and–we actually
implemented Fork in the JVM. I’m not sure if we should have that in the code base because
if someone kind of tries to Fork when you’re running an application on production mode
on an application server, something really big and honking, you can end up having a really
interesting situation when you try and fork that memory. So, I’m not sure if we’re going
to do that. Okay. Sorry, about going back and forth like this. Wow. Ruby 1.9 is really,
really slow for this one. So, this is–this test case is kind of interesting. Define method
is when you define a method and you give it unblocked to–to actually have this implementation
for that one. So, as you can see it’s–it’s really stable. It has this exactly the same
timing for everything. So, I’m going to kill this process. Oh, no. Yeah, right. Ruby 1.9
can’t be killed by control C. Lovely. So, lets do it another way. Okay. I don’t know
why Ruby 1.9 is doing this. Okay. So, now you have seen Ruby 1.9. So, let’s see what
we have. We want to have the server flagged. But that’s not really–that’s really all we
actually need. It–as it turns out, the server flagged in Java 6 especially gives us much
better performance than we–than I would have expected from something like that actually.
The hotspot in Java 6 is actually really good. So, let’s see. This is Java–this is JRuby,
I’m trying it right now, running as Ruby 1.9. So, let’s see the control 0.05 and 0.08 I
would say something like that. Accessing the fix server and calling U to I, that is six
seconds for Ruby 1.9. One second for JRuby. Calling cells through is eight seconds. Yeah.
Eight seconds for Ruby 1.9 and seven seconds for JRuby. And finally, define method: method
is 31 seconds and for JRuby the winner timing is three seconds. So, for this benchmark,
we’re actually faster on everything except for the control. And in one case, we’re actually
ten times faster than Ruby 1.9. So, we’re actually talking about a significant improvement.
And this benchmark, if you’re interested in accessing what we’re testing here. Bench method
dispatched this code. So, define method-method, this defines an empty method with an empty
block and invokes that lots of times. They’re the ones–are kind of similar. This one defines
something on the top self. Top self that returns self which is actually the most–this is the
quickest operation because we always have the self. Returning nil is slightly less efficient
than returning self. And then we have the A to I, and then we have the control up here
which is just accessing. So, this is a control for this one because we actually need to access
the A local variable to be able to call stuff on it. But we don’t want to–yeah, you understand
the benchmarking process here. So, actually that was much better than I expected. I was
amazed about how much faster we were in some situations compared to Ruby 1.9. It’s interesting,
the define method benchmark is actually faster on Ruby 1.8 than it is on Ruby 1.9. But we
still have a significant performance increase compare to them. And this is kind of one of
the most central benchmarks because Meta dispatch is the core of an object oriented language.
The one thing you are doing all the time is Meta dispatch all over the place. So, if we
get this–this fast–and we are actually working in getting it even faster–we can improve
general performance all over the board just by doing that. I told you that the Java integration
stuff–yeah, actually I’ve talked about all those stuff so I’m going to swing by that
one. If you are doing any JRuby stuff, if you want to take at look JRuby and you want
to look at the internals, there are a few things you can do by doing your required JRuby.
One of them is this method call ASC4. It used to be called–actually there is still a method
called that way. It’s used to be called parse. But I prefer ASC4 because this is just–it
takes an expression or a block and it returns to Java AST, the JRuby AST for that. And what
you can do with this AST, you can actually modify AST and you can execute that AST from
this module. So, it’s not really lisp style macros because Ruby has about a hundred different
nodes and they are quite different and quite irregular. So, you won’t do the same kind
of macros but you can actually inspect and change a few things if you put an effort to
it. You compile–you can compile stuff with the JRuby compiler. What you get back at is
this compiled script that you can use to inspect the bytecode. And then you have the more interesting
stuff. You can get the current run time and you can also get the Java integration equivalent
of a Ruby object by calling reference. Now, what you can do with that one is kind of neat.
And it’s not something I re–kind of recommend for actual usage. But what you can do is that
you can freeze a string. And you can get the reference to that string and set the frozen
status on it to false. You can create a class, you can create a new object and you can get
a reference to that one. And then you can set the meta class of that object. Actually
in the effect that becomes–they become command of small.thing. You can get all the methods
of a class like this and actually exchanged the method table at one time if you want to
but that one is not really as compelling as the other ones because you can actually do
this through Ruby methods. All of this is evil stuff but it’s kind of useful if you
want to learn how the implementation actually works. So, I’m going to skip over Rails if
not anyone raises their hand and really want me to talk about Rails.
>>Quick question.>>BINI: Sorry?
>>One quick question. Rails 2.0, how does that work on JRuby?
>>BINI: Rails 2.0, if that works with Ruby? In JRuby?
>>Yeah.>>BINI: Yes. So, the Rails performance is
slightly less than the rest of the performance. So, these benchmarks indicate very good performance
over the board. We–there is some part of Rails–and this is true for both Rails 1.2
and Rails 2.0, that we haven’t been able to identify that cause this performance to drop.
That means that we are still faster with JRuby. We have a smaller memory print than we do
in the equivalent de–deployment with Mongrels. But it means that we are not as fast as we
should be. We should be two to three times faster. Right now we can maybe we have 120%
on one–the Ruby 1.8, in general. It’s kind of hard to benchmark though, because we don’t
have anything that we can use as a reference for benchmarking. This is actually something
we are working on getting some–getting to get us something that we can use as a reference,
that we can use as reference for numbers so we can actually improve the performance with
focus on Rails performance because it’s important that we find this bottleneck. There is something
strange going on. Yes?>>So, you’re talking about runtime performance.
I assume it’s [INDISTINCT]>>BINI: Yeah.
>>How much better is the memory footprint?>>BINI: So, the memory footprint, it kind
of depends on what you’re doing. If you’re doing stuff that cycles lots of methods and
creates new methods, quite a lot at runtime. The compiler will take out more PermGen space
because classes go into PermGen space. But overall with–compared to Mongrel–Paul, do
you remember David has told us about this. I don’t have the numbers. We’re not talking
magnitudes of difference. We’re not talking–we’re maybe talking half the memory footprint to
get the same requests per second, something like that. Yes?
>>So how do you actually deploy a Rails application with JRuby? Do you run inside an app server
like COMPAQ?>>BINI: So, I see. I actually have this somewhere.
No. So, I was planning on doing some demonstrations but I’m running out of time so I’m going to
skip that one. It’s not really an interesting demonstration if you have seen the–if you
have seen the Rails Podcast–Rails screencast when they do a blog. So, the thing about it
is that Rails works exactly like it does on regular Ruby. But you have a few different
deployment options. First of all you can deploy exactly like you could do with regular–regular
Ruby, but you don’t want to have 10 Mongrels running in their own JVM. So, there is another
way that you can use a Mongrel cluster that actually runs inside of the one JVM but uses
different runtimes. Since JRuby is by the–by design multi-virtual machine, so you can use
one more than JRuby version virtual machine inside of the same–actually, one of the fun
things we do in our test processes that we use JRuby scripts to start new JRuby runtimes
inside of those JRuby scripts and we script them from the outside to do tests on the internal
runtime. We can do all the stuff because we don’t have any shared safe. We don’t have
any singletons. Now, Mongrel cluster works, kind of, if you’re stuck in a Ruby mindset.
But there are two ways of doing stuff that is much more convenient. The first one is
to do, you know, something called GlassFish. You have heard of GlassFish, right? So GlassFish
is really cool and they have a gem. A gem that is 2.2 megs large. You install it saying–gem.install
GlassFish. And what you get back is a GlassFish Rails command that you can start any JRuby
on Rails application with. You don’t need to do any configuration. It just works from
scratch and you can do it in development mode, it picks up. You can start several runtimes,
so you can try performance and so on. And you get the whole application server, the
whole GlassFish in 2 megs of a gem. That is an interesting option. It’s not necessarily
good for deployment. It’s good if you’re going to deploy on a GlassFish server that exists
somewhere that someone takes care off. Then it’s good to do that development locally in
the same environment. But I will say the recommended way of doing deployment is by taking one of
the existing–there are few plug-ins of doing this; Warbler, JRuby works, and Goldspike.
They allow you to package everything up into a WAR file. So they give you–you install
them as a plug-in then you create some–you–sometimes you need to create some actual configuration
to point out which gems you need. Because all of these create WAR files that are actually
self contained archives that contain the JRuby runtime and all the gems need it, all the
libraries need it. So, you need to create the WAR–you need to point out the gems that
need to be included. You possibly need to change your web.xml. And then you get a WAR
file out that you just deploy. The process is extremely simple and you get a WAR file
that can be deployed in any compliant Java web application container. This is the preferred
way of doing it. You have–you can have a few other ways of doing it too. Right now,
for example, Mingle, which I’m coming to you in a few slides, is a bundled application
that we bundle. And we send out bundles so people can install it locally. And the way
that works is basically that when it starts up, it starts up an internal Yeti that serves
Ruby, that handles the JRuby runtimes using the Goldspike server that–which is–it’s
a Rail servlet that allows you to set–all of these projects can use the Rail servlet
to actually serve the Rail’s content, so those are the options. And the best one for real
production is to just push out the–push out a WAR file and deploy that the way would do
any Java application. Because in that case you also get all moni–monitoring benefits,
you get all the management benefits, you get all the clustering, you get security, you
get some other transactions of what–you can get all of that for free by just putting it
in a WAR file. So, a few different things that kind of can be useful to know about around
the JRuby ecosystem in–outside of Rails they’re actually–there is actually a world outside
of Rails. One of the posh that I like to think about and I think I’ve been test infected
since I had joined ThoughtWorks. I’ve talked a lot about tests before that but–yeah. So,
in good ThoughtWorks manner I have created my own testing framework. This is a testing
framework that doesn’t really create anything from scratch. It’s just a bundling of stuff.
It put things together and makes it really easy for you to use Ruby frameworks to test
your Java code. So this is for those situations where maybe you need to have Java code in
your main product for some reason but you have some flexibility to use something else
for tests. So JtestR glues JRuby together which RSpec, Test Unit, dust, Mocha, and a
few other libraries. So, it gives you flexibility in which test framework you want to use. It
doesn’t really matter. You get Ant and Maven 2 integration and you can also interact back
with J Unit of test NJ tests that you have written earlier that you want to include in
your stuff, so–and all of this generates a unified output if you want that. The RSpec
support actually have support for Story. So if you want to do behavior driven development
with Story as acceptance criteria, this is a very nice way of doing it. Off the record
it’s nice, it’s simple, it’s not scalable. Hibernate is. So we are working on something
to kind of put the easiness of defining stuff in ActiveRecord and working with ActiveRecord
and the easiness of the Ruby language together with Hibernate. So this is just a proof of
concept. The product is still going on but we don’t really have the resources to put
lots of man-hours behind it right now. The purpose is basically to be able to do something
that is in spirit like ActiveRecord, but uses the base of Hibernate and also allow you to
reuse your existing investment in Hibernate. Yes?
>>That has to be ran inside of JRuby?>>BINI: This is a JRuby thing, yes. You could
imagine possibly doing that with RJB or something like that, but it wouldn’t really be feasible.
You can do it but it would be painful to say the least. So this section depends on having
Hibernate–the Hibernate libraries on a class but uses Java integration–the Java integration
features of JRuby. We have discovered that Java is a very good platform. But it’s not
the best platform in the world for dynamic languages right now. So we’re working on improving
the situation by JSR292 something that we call JLR and the Da Vinci Machine. And all
of this kind of aim to provide more cool stuff in the next Java version that allows other
implementations to live well. The most important one is the dynamic invocation–invoke dynamic.
You have method handles, anonymous classes, faster reflections, escape analyst; all of
these stuff is kind of important. And now you have the more cool stuff that is, kind
of, probably not going to happen but could be interesting if it happened. Interface injection,
real mixins in the Java platform. Continuations, value objects, tuple types might possibly
happen actually, tail calls would be really good for many languages. I’m not sure if tail
call optimization is going to happen or not. But all of this is going to be–is being prototyped
in the Da Vinci Machine right now. Finally, I just want to show a few examples of stuff
where people actually use–oh, yeah. Sorry. Yes?
>>So, like, maybe 80% of that stuff is already in CLR like in Mono and stuff like that. So
does that mean like for IronRuby and Ruby.net that they’re going to be faster than JRuby
on some of these things because they don’t have to do as much [INDISTINCT]
>>BINI: So, I would post it that most of this stuff is not in the CLR. Is it? I don’t
think that most of this stuff is available in the CLR.
>>[INDISTINCT] Continuation, value objects…>>BINI: No, no, no. Dynamic imitation uses
dynamic call sites from DLR. It’s a library on top of CLR. There is no support in the
CLR in Mono for actually–for doing this, so this just library level on top of the CLR.
There is no support in the actual virtual machine for these things. So what we’re talking
about here is actually a new byte code.>>Oh, okay.
>>BINI: So that’s going to change the Story. The way it did the DLR stuff, do–it does
things is that they–one thing they do have is method handles. And the dynamic call sites,
they have a–the–it’s a class–it’s a generous sized class that allows them to quickly and
perfomantly switch out method handles. But they don’t have support from a virtual machine,
so they don’t get any actual adjust-in-time compilation and so on. So I would say if we
get this–actually, even if we don’t get it, we still are in a better situation than the
CLR for performance right now for the simple reason that the CLR is not–and this stuff
that was actually reported back from the Lang.NET event in January. The CLR doesn’t do much
of the hotspot optimization that Java does currently. Java’s hotspot, has lots of interesting
stuff that CLR still doesn’t do. So, general performance is going to take some time for
the CLR to catch up.>>Do you mean hotspot in Java 1.6 specifically
or the one…>>BINI: No. In Java–in general–in some
JDKs, the Java 6 hotspot is more advanced but still the Java 1.4 hotspot is more advanced
than what you can find in the actual CLR implementations. Oracle actually released mix.oracle.com and
that is a JRuby on Rail site. We built it in six weeks and it’s, kind of, sharing net–idea
sharing networking Q&A production environment for all of Oracle’s customers. And it runs
on top of a full Oracle stack. And one of the reasons was that the production staff
wouldn’t actually be able to get MRI into the resulting stuff. And they also wanted
to be able run on top of the full application–Oracle application stack. So, this is actually running
with using–let’s see, Oracle SSO, Oracle Directory server, Oracle Apache, Oracle Linux,
Oracle RDBMS, and Oracle Application Service. So it’s, kind of, the red stack from top to
bottom. Sun is doing something called MediaCAST that is kind of mini-marketing distribution
channel using JRuby on Rails. And then we have, ThoughtWorks, this released a product
called Mingle. Now, this is kind of a screenshot of how the general interface works. It’s the
first JRuby project to–product to ever be released. It was released on June. The 2.0
version is going to be in sometime in March. It’s kind of for collaboration and agile workflow,
but it doesn’t restrict you in any way. Cards are basically the only restrict–abstraction
you have and you can use that to do quite flexible things actually. We use that for–we
use JRuby for several reasons. We ended up in a situation where we needed a library that
we couldn’t get to work on both Linux and Windows in the Rail or Ruby distribution.
So we went to JRuby and used the Java library and that works perfectly, then we ended up
using some other things too. For example, Darby we used for long time. We use JRuby
to be able to actually protect and encrypt the source code of the Ruby application. And
we’re probably going to go away from doing that and just use pre-compilation instead
because precompiled JRuby bytecode is incredibly unreadable. It’s better than the best [INDISTINCT].
You’re not going to actually understand what’s happening there without some serious analysis,
which is nice. JRuby allowed us to do easy bundling too. So, all of these kind of benefits.
So that’s actually the end of my talk. And this is the book I mentioned earlier and I
didn’t actually add any resources because all this stuff is very easy to find with a
well-known search engine.>>[INDISTINCT] mentioned earlier.
>>BINI: Exactly. So–right. So, are there anymore questions? Yes?
>>Okay. If we can use the mic so we get it for the video.
>>So when you marshal between the JRuby interpreter and Java when you’re, like, making new buttons
and stuff, like, what’s the–what’s the overhead for the marshalling between the two? Like,
how many objects are made and thrown away?>>BINI: The Java integration marshalling?
>>Right, yeah.>>BINI: Yes.
>>When you made a button and whatever. Like, how many extra objects are made in stuff like
that?>>BINI: So, at creation of new objects the
most stuff that happens–that’s a good question actually. Because that’s the area we’re going
to spend lots of time after the 101 release. Now, the Java integration features are extremely
complex right now. And the implementation have kind of grown organically when we need
the new features. So right now, two times new objects are being created. First time,
when you actually use the class–a Java class for the first time. At that point, lots of
different object are created to actually represent the Java methods and all the metadata structure
that we need to be able to do the Ruby kind of features on top of the Java stuff.
>>Okay.>>BINI: And then, I think two pri–two objects
are usually created for every one Java object you create like that because they always need
at least one wrapper. I–if I remember correctly, you don’t need more than one wrapper but all
of this is going to be revisited. We are going to rip it all out and redo it. Because now
we know how the interface is going to look. We know how the integration is actually going
to work. We just need to implement it better and more performance.
>>And do those wrapper objects have the same or–I’m assuming they’re wrappers–do they
have the same lifetime as the object itself or they’re made and then thrown away relatively
quickly?>>BINI: That’s a good question. I would assume–I–I’m–so
they don’t have the same lifetime that’s obvious if–the wrapper object had the same lifetime
as the objects are referenced–as long as the reference–obvious the reference from
the Ruby side of stuff. So if you pass something back into Java and that local variable and
Ruby goes out of scope, yes, the wrapper object is going to be collected.
>>Okay. And is there any objects that–like, those that are made for this method calls
after you create the Java object within Ruby? So, if you make an object and then you call
method, is there going to be any extra GC overhead just from calling methods in that
object that you already created or no?>>BINI: No. So, the only thing that’s going
to happen is the wrapping and unwrapping of parameters to that call. So, that might be
something there. But we’re–we’re moving quite heavily towards lightweights and that’s also
one of the major instructions we are looking at making–to actually make–right now everything
is wrapped. But we want to make it lightweights.>>Right.
>>BINI: So, we can actually work around–there–there are some challenges in doing lightweights
and implementation. But I think that–especially when you have a language like Java that doesn’t
actually have a unified object structure. But we think we can work around with them.
It’s going to be lots of benefits in many cases especially no wrappers and stuff like
that, of course.>>So, does the Hotspot–one last question.
Does the Hotspot VM in 1.6 or 1.7 or whatever, inline to the point were the method indication
overhead for these wrappers is non-existent or does it not inline at all?
>>In between. It does inline and it does improve performance self-invocation of these.
But the problem, for Hotspot is the power usage patterns for the stuff. It’s kind of
not what Hotspot expects. So, the problem–this is a problem with Java one–it’s not a problem
with Java 1.6. It’s a problem with algorithms used up until Java 1.6. Because the Hotspot
optimize is based on current Java IDMS and what current Java idioms compile into, which
is why we should write simple Java code because that is easier to Hotspot compile. Now Java
1.7 is actually going to be much smarter and optimized all kind of bytecodes combinations
in a much smarter way without taking into account IDMS like that. So, that’s going to
improve the situation. And it’s kind of funny when we–when we upgraded, when we started
testing performance in 1.6 instead of 1.5, just the Hotspot in running a server gave
us twice the performance just by upgrading. We didn’t do anything. That’s–that’s the
best kind of performance improvement I like, the ones where I don’t have to do any work
for them. Yes, any more questions?>>Thanks. Two good questions. One, in terms
of compatibilities is it generally safe to assume that pretty much any Ruby application
or Ruby library that doesn’t use native extensions works with JRuby as well?
>>BINI: Yes.>>So, if I wanted to use something like the
Merb, what framework with…>>BINI: Yeah, Merb is a good example of something
that actually has native extensions.>>Oh, okay.
>>BINI: But Merb is–but Merb works because we have ported native extension. Merb use
is the HTTP parsive, and from Mongrel which is actually the only C competent of Mongrel.
It’s a regal state machine and since a regal–regal is really cool by the way if you–if like
a–if you need to cite some theory it’s really nice since it has an output node for Java,
what we need to do is essentially just porch the small helpful methods in their C regal
definition. And then we can just generate a Java parser for HTTP that works as well.
So, that was actually a quick process so–since that is available that means that Merb works
fine.>>Okay. And another quick one. Is it possible
to share gems between the regular Ruby VM and then JRuby VM on the same system?
>>BINI: Yes. We don’t generally do it because there are lots of gems that are kind of JRuby
specific. And if in some cases–in some cases it actually happens because they’re–the way
they are, if you used JRuby to install a gem that is Java specific into your shared gem
repository, when Ruby as Ruby gems tries to load the manifest for all these–because it
keeps a manifest running up all the install and stuff, right? So, when it tries to load
out, it’s going to barf and saying “Well, I can’t have this in my manifest.” and then
it’s just going to go poof and say–it’s actually not going to say anything, if I remember correctly.
It just barfs on you. So, if you want to have shared, that’s fine. But be careful to not
put any Java specific stuff there.>>All right, makes sense.
>>BINI: Okay. Any more questions? Yeah. Right, there?
>>So, compatibility question RubyCocoa is one.
>>BINI: I’m sorry?>>RubyCocoa?
>>BINI: I’m sorry. I don’t hear what you’re…>>RubyCocoa
>>BINI: RubyCocoa?>>The framework on Leopard.
>>BINI: Okay.>>For rating Cocoa apps on Ruby.
>>BINI: Oh, Cocoa. Sorry. Yes.>>The network with the–to Ruby? Does that
work?>>BINI: I haven’t tried it. I would assume
it kind of extends–it uses native extensions. But there is a Java interface–interfacing
with objective C on that way.>>It’s been deprecated.
>>BINI: What?>>I think that’s been deprecated.
>>BINI: All right. And that stopped anyone?>>Hmm.
>>BINI: Sorry. Deprecation never stops anyone. No, so yeah. As far as I know, no one has
actually tried to interface JRuby with Cocoa right now. There–as long as there is some
way for us to get in there, it should be possible. But on the other hand, Apple has actually
spent lots of time writing integration, things and writing lots of C code and C–I have yet
to see–to integrate–integrate Ruby with Cocoa. So, I’m not sure that’s going to happen
in just a blink of an eye.>>Right. What about the Autotest?
>>BINI: Autotest? Yes. If I remember correctly we have that working. There were one or two
command line options we didn’t support for a long time and that kind of stopped it from
working. We have fixed that.>>Cool.
>>BINI: Any more questions? Okay, great.>>Great.
>>BINI: Thank you for having me here>>Well, thank you so much for having Ola.