Archive
The Merbification of Rails
It’s been a few weeks since the announcement that Rails 3 would be Merb 2. We had a discussion on our local Phoenix RUG list, my input to which is here. Then I dug around some more and read the posting by DHH.
This is not a big bang rewrite
So, Rails 3 will be Rails 2 + some unspecified but core stuff from Merb moved over. And Merb 2 will be … ? If you’re a rails developer, this is probably not big news in any way, just wait for Rails 3 to be released (or RC status) and figure out what breaks, if you intended to upgrade at all. However, if you are a Merb developer, or about ready to pick up Merb (like me) this puts you in a pretty bad spot. Do I learn Merb for all its touted benefits of lean execution and component agnosticism? Well I could, and then later this year re-learn all over when the API’s change in Rails 3. The Merb community is saying “come to Merb, it’s like getting a preview of Rails 3″.
That makes this training basically the first training focusing on the future features of Rails 3, and a great way to get ahead of the game. – Yehuda Katz
Except that this is not true. The Merb API will change when it is merged into Rails. ActiveRecord is remaining as the default ORM layer and I am positive that other Rails elements will persist. Merb will be Railsified I think as much as Rails will be Merbified. How do you withstand hundreds (thousands?) of plugin authors shouting at you to not break things. I don’t even want to imagine the compromises that will be made when all the users catch on to the idea that lots of API’s will be changing.
Unfortunately I think a clean break is the best possible solution. Merb was started because Ezra claimed it was far easier to rewrite portions of Rails than try to fix the existing code. Heck, Merb itself was rewritten from scratch recently with no apparent universe imploding effects so they’ve proven it can be done on a large code base. Yet we have the situation where DHH will not let go of Rails (his code) to make way for what he to some degree is acknowledging as a better solution. So my grand hopes of a stack that has all the marketing and acceptance of Rails but the clean implementation of Merb deflates daily. Moreso, my desire to learn Merb drops to almost zero, I might as well stick with Rails since a) I know it and can move much quicker, b) The Merb API is going to change anyway, c) I suspect we’ll end up closer to Rails than to Merb in the end, at least on the surface.
JRuby, still the fastest Ruby implementation
A fairly comprehensive benchmark test has been run across all available (and even some pending) Ruby implementations.
JRuby continues to be the fastest 1.8 compatible implementation by quite a long way.
What Ruby developers really want
What’s your biggest beef with Ruby today? A need for a better thought out sandbox model, people conflating Ruby and Rails (my personal vote), or some other issue? For 50% of Ruby Inside readers it appears to be performance. This is interesting because it’s one of the easiest things that can be remedied RIGHT NOW. Yup, just switch to JRuby and (barring some native extension problems) you’re up and running and faster. Sometimes this performance boost is quite significant as the JRuby team regularly demonstrates in their blog posts. So what are you waiting for, go grab the fastest Ruby available and start enjoying that performance!
Java game library + JRuby + awesome DSL = Gemini
I’ve been working with JRuby to build high level systems on top of powerful Java libraries for about 2 years now. My most successful endeavor has been Monkeybars, a libarary for making Swing a lot easier to use. My other project has been in the game development arena. The project name is Gemini, and although it’s not nearly as advanced as Monkeybars, I was able to get to a significant point over the weekend. Yes, here in all its glory, the simple “crapton of sprites bouncing back and forth demo”.
Now you’re probably saying, big deal, I can do that in like 40 lines of code in <insert favorite programming language/framework> and no doubt you would be correct. What’s interesting about the way Gemini does things is in how it gives you an extremely flexible way of compositing together your game objects and your application as a whole.
The code to get this going using Gemini is pretty straightforward. We have a game state that is loaded by Gemini when it starts up. That game state then instantiates 1000 of our game objects and they proceed to load their images and care for their own logic of bouncing around on the screen.
Here’s the code in main.rb that kicks off the app:
require 'gemini'
Gemini::Main.new("Test game", 640, 480)
And here is the state that is loaded by default when Gemini runs: main_state.rb
class MainState < Gemini::BaseState
def load
@sprites = []
1000.times {@sprites << Duke.new}
end
def update(delta)
@sprites.each { |sprite| sprite.update(delta) }
end
def render(graphics)
@sprites.each { |sprite| sprite.draw }
end
end
Finally we have the Duke class that was instantiated in the MainGame class:
class Duke < Gemini::GameObject
has_behavior :Movable2D
has_behavior :Sprite
has_behavior :UpdatesAtConsistantRate
def load
self.image = "duke.png"
self.updates_per_second = 30
@direction = :right
self.x = rand(640 - image.width)
self.y = rand(480 - image.height)
end
def tick
if x > (640 - image.width) || x < 0
@direction = @direction == :right ? :left : :right
end
self.x = x + (@direction == :right ? 1 : -1)
end
end
Apart from some hackish ternary ifs in the Duke class I think the whole thing is pretty darn readable, especially considering all that it is doing. As you can see, everything is extremely declarative including those has_behavior calls in the Duke class. Those nifty bits of metaprogramming bring in all the crunchy goodness of the class and make the x, y, image and updates_per_second methods appear. Movable2D gives us a move method and also pulls in the Positional2D behavior that provides the x and y methods. UpdatesAtConsistantRate gives us an update method that calls tick at the rate specified by updates_per_second. Finally the Sprite behavior gives us the image method and the draw method that gets called in the MainGame class.
Most of this is bare bones at the moment. What if you don’t have the UpdatesAtConsistantRate? When update is called you asplode. Same for Sprite / render. So clearly a more flexible game state is needed, probably involving the game object behaviors auto-registering themselves with the game state to be called during an update/render cycle. But as a whole I’m quite happy with the way Gemini is starting to shape up. Next on the agenda is getting keyboard mapping hooked into the RecievesKeyboardEvents behavior so you can control duke, then we’ll have what could pass for a real game.



