Let’s Build a Simple Video Game with JRuby: A Tutorial »
Created at: 15.12.2011 02:34, source: Ruby Inside, tagged: Cool jruby Tutorials
Ruby isn't known for its game development chops despite having a handful of interesting libraries suited to it. Java, on the other hand, has a thriving and popular game development scene flooded with powerful libraries, tutorials and forums. Can we drag some of Java's thunder kicking and screaming over to the world of Ruby? Yep! - thanks to JRuby. Let's run through the steps to build a simple 'bat and ball' game now.

The Technologies We'll Be Using
JRuby
If you're part of the "meh, JRuby" brigade, suspend your disbelief for a minute. JRuby is easy to install, easy to use, and isn't going to trample all over your system or suck up all your memory. It will be OK!
One of JRuby's killer features is its ability to use Java libraries and generally dwell as a first class citizen on the JVM. JRuby lets us use performant Java powered game development libraries in a Rubyesque way, lean on Java-based tutorials, and basically have our cake and eat it too.
To install JRuby, I recommend RVM (Ruby Version Manager). I think the JRuby core team prefer you to use their own installer but rvm install jruby has always proven quick and effective for me. Once you get it installed, rvm use jruby and you're done.
Slick and LWJGL
The Slick library is a thin layer of structural classes over the top of LWJGL (Lightweight Java Game Library), a mature and popular library that abstracts away most of the boring system level work.
Out of the box LWJGL gives us OpenGL for graphics, OpenAL for audio, controller inputs, and even OpenCL if we wanted to do heavy parallelism or throw work out to the GPU. Slick gives us constructs like game states, geometry, particle effects, and SVG integration, while allowing us to drop down to using LWJGL for anything we like.
Getting Started: Installing Slick and LWJGL
Rather than waste precious time on theory, let's get down to the nitty gritty of getting a basic window and some graphics on screen:
- First, create a folder in which to store your game and its associated files. From here I'll assume it's
/mygame - Go to the Slick homepage and choose "Download Full Distribution" (direct link to .zip here).
- Unzip the download and copy the
libfolder into your/mygameas/mygame/lib- this folder includes both LWGWL and Slick. - In
/mygame/lib, we need to unpack thenatives-[your os].jarfile and move its contents directly into/mygame.Mac OS X: Right click on the
natives-mac.jarfile and select to unarchive it (if you have a problem, grab the awesome free The Unarchiver from the App Store) then drag the files in/mygame/lib/native-mac/*directly into/mygame.Linux and Windows: Running
jar -xf natives-linux.jarorjar -xf natives-win32.jarand copying the extracted files back to/mygameshould do the trick. - Now your project folder should look a little like this:

If so, we're ready to code.
A Bare Bones Example
Leaping in with a bare bones example, create /mygame/verybasic.rb and include this code:
$:.push File.expand_path('../lib', __FILE__)
require 'java'
require 'lwjgl.jar'
require 'slick.jar'
java_import org.newdawn.slick.BasicGame
java_import org.newdawn.slick.GameContainer
java_import org.newdawn.slick.Graphics
java_import org.newdawn.slick.Input
java_import org.newdawn.slick.SlickException
java_import org.newdawn.slick.AppGameContainer
class Demo < BasicGame
def render(container, graphics)
graphics.draw_string('JRuby Demo (ESC to exit)', 8, container.height - 30)
end
# Due to how Java decides which method to call based on its
# method prototype, it's good practice to fill out all necessary
# methods even with empty definitions.
def init(container)
end
def update(container, delta)
# Grab input and exit if escape is pressed
input = container.get_input
container.exit if input.is_key_down(Input::KEY_ESCAPE)
end
end
app = AppGameContainer.new(Demo.new('SlickDemo'))
app.set_display_mode(640, 480, false)
app.start
Ensure that ruby actually runs JRuby (using ruby -v) and then run it from the command line with ruby verybasic.rb. Assuming all goes well, you'll see this:

If you don't see something like the above, feel free to comment here, but your problems most likely orient around not having the right 'native' libraries in the current directory or from not running the game in its own directory in the first place (if you get probable missing dependency: no lwjgl in java.library.path - bingo).
Explanation of the demo code
$:.push File.expand_path('../lib', __FILE__)pushes the 'lib' folder onto the load path. (I've usedpushbecause my preferred << approach breaks WordPress ;-))require 'java'enables a lot of JRuby's Java integration functionality.- Note that we can use
requireto load the .jar files from the lib directory. - The
java_importlines bring the named classes into play. It's a little likeinclude, but not quite. - We lean on Slick's
BasicGameclass by subclassing it and adding our own functionality. renderis called frequently by the underlying game engine. All activities relevant to rendering the game window go here.initis called when a game is started.updateis called frequently by the underlying game engine. Activities related to updating game data or processing input can go here.- The code at the end of the file creates a new
AppGameContainerwhich in turn is given an instance of our game. We set the resolution to 640x480, ensure it's not in full screen mode, and start the game.
Fleshing Out a Bat and Ball Game
The demo above is something but there are no graphics or a game mechanic, so it's far from being a 'video game.' Let's flesh it out to include some images and a simple pong-style bat and ball mechanic.
Note: I'm going to ignore most structural and object oriented concerns to flesh out this basic prototype. The aim is to get a game running and to understand how to use some of Slick and LWJGL's features. We can do it again properly later :-)
All of the assets and code files demonstrated here are also available in an archive if you get stuck. Doing it all by hand to start with will definitely help though.
A New Code File
Start a new game file called pong.rb and start off with this new bootstrap code (very much like the demo above but with some key tweaks):
$:.push File.expand_path('../lib', __FILE__)
require 'java'
require 'lwjgl.jar'
require 'slick.jar'
java_import org.newdawn.slick.BasicGame
java_import org.newdawn.slick.GameContainer
java_import org.newdawn.slick.Graphics
java_import org.newdawn.slick.Image
java_import org.newdawn.slick.Input
java_import org.newdawn.slick.SlickException
java_import org.newdawn.slick.AppGameContainer
class PongGame < BasicGame
def render(container, graphics)
graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30)
end
def init(container)
end
def update(container, delta)
input = container.get_input
container.exit if input.is_key_down(Input::KEY_ESCAPE)
end
end
app = AppGameContainer.new(PongGame.new('RubyPong'))
app.set_display_mode(640, 480, false)
app.start
Make sure it runs, then move on to fleshing it out.
A Background Image
It'd be nice for our game to have an elegant background. I've created one called bg.png which you can drag or copy and paste from here (so it becomes /mygame/bg.png):
Now we want to load the background image when the game starts and render it constantly.
To load the game at game start, update the init and render methods like so:
def render(container, graphics)
@bg.draw(0, 0)
graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30)
end
def init(container)
@bg = Image.new('bg.png')
end
The @bg instance variable picks up an image and then we issue its draw method to draw it on to the window every time the game engine demands that the game render itself. Run pong.rb and check it out.
Adding A Ball and Paddle
Adding a ball and paddle is similar to doing the background. So let's give it a go:
def render(container, graphics)
@bg.draw(0, 0)
@ball.draw(@ball_x, @ball_y)
@paddle.draw(@paddle_x, 400)
graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30)
end
def init(container)
@bg = Image.new('bg.png')
@ball = Image.new('ball.png')
@paddle = Image.new('paddle.png')
@paddle_x = 200
@ball_x = 200
@ball_y = 200
@ball_angle = 45
end
The graphics for ball.png and paddle.png are here. Place them directly in /mygame.
We now have this:

Note: As I said previously, we're ignoring good OO practices and structural concerns here but in the long run having separate classes for paddles and balls would be useful since we could encapsulate the position information and sprites all together. For now, we'll 'rough it' for speed.
Making the Paddle Move
Making the paddle move is pretty easy. We already have an input handler in update dealing with the Escape key. Let's extend it to allowing use of the arrow keys to update @paddle_x too:
def update(container, delta)
input = container.get_input
container.exit if input.is_key_down(Input::KEY_ESCAPE)
if input.is_key_down(Input::KEY_LEFT) and @paddle_x > 0
@paddle_x -= 0.3 * delta
end
if input.is_key_down(Input::KEY_RIGHT) and @paddle_x < container.width - @paddle.width
@paddle_x += 0.3 * delta
end
end
It's crude but it works! (P.S. I'd normally use && instead of and but WordPress is being a bastard - I swear I'm switching one day.)
If the left arrow key is detected and the paddle isn't off the left hand side of the screen, @paddle_x is reduced by 0.3 * delta and vice versa for the right arrow.
The reason for using delta is because we don't know how often update is being called. delta contains the number of milliseconds since update was last called so we can use it to 'weight' the changes we make. In this case I want to limit the paddle to moving at 300 pixels per second and 0.3 * 1000 (1000ms = 1s) == 300.
Making the Ball Move
Making the ball move is similar to the paddle but we'll be basing the @ball_x and @ball_y changes on @ball_angle using a little basic trigonometry.
If you stretch your mind back to high school, you might recall that we can use sines and cosines to work out the offset of a point at a certain angle within a unit circle. For example, our ball is currently moving at an angle of 45, so:
Math.sin(45 * Math::PI / 180) # => 0.707106781186547
Math.cos(45 * Math::PI / 180) # => 0.707106781186548
Note: The * Math::PI / 180 is to convert degrees into radians.
We can use these figures as deltas by which to move our ball based upon a chosen ball speed and the delta time variable that Slick gives us.
Add this code to the end of update:
@ball_x += 0.3 * delta * Math.cos(@ball_angle * Math::PI / 180)
@ball_y -= 0.3 * delta * Math.sin(@ball_angle * Math::PI / 180)
If you run the game now, the ball will move up and right at an angle of 45 degrees, though it will continue past the game edge and never return. We have more logic to do!
Note: We use -= with @ball_y because sines and cosines use regular cartesian coordinates where the y axis goes from bottom to top, not top to bottom as screen coordinates do.
Add some more code to update to deal with ball reflections:
if (@ball_x > container.width - @ball.width) || (@ball_y < 0) || (@ball_x < 0)
@ball_angle = (@ball_angle + 90) % 360
end
This code is butt ugly and pretty naive (get ready for a nice OO design assignment later) but it'll do the trick for now. Run the game again and you'll notice the ball hop through a couple of bounces off of the walls and then off of the bottom of the screen.
Resetting the Game on Failure
When the ball flies off of the bottom of the screen, we want the game to restart. Let's add this to update:
if @ball_y > container.height
@paddle_x = 200
@ball_x = 200
@ball_y = 200
@ball_angle = 45
end
It's pretty naive again, but does the trick. Ideally, we would have a method specifically designed to reset the game environment, but our game is so simple that we'll stick to the basics.
Paddle and Ball Action
We want our paddle to hit the ball! All we need to do is cram another check into update (poor method - promise to refactor it later!) to get things going:
if @ball_x >= @paddle_x and @ball_x < = (@paddle_x + @paddle.width) and @ball_y.round >= (400 - @ball.height)
@ball_angle = (@ball_angle + 90) % 360
end
Note: WordPress has borked the less than operator in the code above. Eugh. Fix that by hand ;-)
And bingo, we have it. Run the game and give it a go. We have a simple, but performant, video game running on JRuby.
If you'd prefer everything packaged up and ready to go, grab this archive file of my /mygame directory.
What Next?
Object orientation
As I've taken pains to note throughout this article, the techniques outlined above for maintaining the ball and paddle are naive - an almost C-esque approach.
Building separate classes to maintain the sprite, position, and the logic associated with them (such as bouncing) will clean up the update method significantly. I leave this as a task for you, dear reader!
Stateful Games
Games typically have multiple states, including menus, game play, levels, high score screens, and so forth. Slick includes a StateBasedGame class to help with this, although you could rig up your own on top of BasicGame if you really wanted to.
The Slick wiki has some great tutorials that go through various elements of the library, including a Tetris clone that uses game states. The tutorials are written in Java, naturally, but the API calls and method names are all directly transferrable (I'll be writing an article about 'reading' Java code for porting to Ruby soon).
Packaging for Distribtion
One of the main reasons I chose JRuby over the Ruby alternatives was the ability to package up games easily in a .jar file for distribution. The Ludum Dare contest involves having other participants judge your game and since most participants are probably not running Ruby, I wanted it to be relatively easy for them to run my game.
Warbler is a handy tool that can produce .jar files from a Ruby app. I've only done basic experiments so far but will be writing up an article once I have it all nailed.
Ludum Dare
I was inspired to start looking into JRuby and Java game libraries by the Ludum Dare game development contest. They take place every few months and you get 48 hours to build your own game from scratch. I'm hoping to enter for the first time in just a couple of days and would love to see more Rubyists taking part.
more »
Ruby’s Unary Operators and How to Define Their Functionality »
Created at: 08.11.2011 19:27, source: Ruby Inside, tagged: Tutorials
In math, a unary operation is an operation with a single input. In Ruby, a unary operator is an operator which only takes a single 'argument' in the form of a receiver. For example, the - on -5 or ! on !true.
In contrast, a binary operator, such as in 2 + 3, deals with two arguments. Here, 2 and 3 (which become one receiver and one argument in a method call to +).
Ruby only has a handful of unary operators, and while it's common to redefine binary operators like + or [] to give your objects some added syntactic sugar, unary operators are less commonly redefined. In my experience, many Rubyists aren't aware that unary operators can be redefined, so this article demonstrates how.
A Quick Example with -@
Let's ease into things with the - unary operator. The - unary operator is not the same thing as the - binary operator (where a binary operator has two operants). By default, the - unary operator is used as notation for a negative number, as in -25, whereas the - binary operator performs subtraction, as in 50 - 25. While they look similar, these are different concepts, different operators, and resolve to different methods in Ruby.
Using the - unary operator on a string in irb:
ruby-1.9.3-p0 :001 > -"this is a test"
NoMethodError: undefined method `-@' for "this is a test":String
The String class doesn't have unary - defined but irb gives us a clue on where to go. Due to the conflict between the unary and binary versions of -, the unary version has a suffix of @. This helps us come up with a solution:
str = "This is my STRING!"
def str.-@
downcase
end
p str # => "This is my STRING!"
p -str # => "this is my string!"
We've defined the unary - operator by defining its associated -@ method to translate its receiving object to lower case.
Some Other Operators: +@, ~, ! (and not)
Let's try a larger example where we subclass String and add our own versions of several other easily overridden unary operators:
class MagicString < String
def +@
upcase
end
def -@
downcase
end
def !
swapcase
end
def ~
# Do a ROT13 transformation - http://en.wikipedia.org/wiki/ROT13
tr 'A-Za-z', 'N-ZA-Mn-za-m'
end
end
str = MagicString.new("This is my string!")
p +str # => "THIS IS MY STRING!"
p !str # => "tHIS IS MY STRING!"
p (not str) # => "tHIS IS MY STRING!"
p ~str # => "Guvf vf zl fgevat!"
p +~str # => "GUVF VF ZL FGEVAT!"
p !(~str) # => "gUVF VF ZL FGEVAT!"
This time we've not only redefined -/-@, but the + unary operator (using the +@ method), ! and not (using the ! method), and ~.
I'm not going to explain the example in full because it's as simple as I could get it while still being more illustrative than reams of text. Note what operation each unary operator is performing and see how that relates to what is called and what results in the output.
Note: You cannot redefine ! in Ruby 1.8. This code performs as-is in Ruby 1.9 only. If you remove the ! method and examples, the code otherwise works in Ruby 1.8. There's a longer 1.8 and 1.9 example later in this post.
Special Cases: & and *
& and * are also unary operators in Ruby, but they're special cases, bordering on 'mysterious syntax magic.' What do they do?
& and to_proc
Reg Braithwaite's The unary ampersand in Ruby post gives a great explanation of &, but in short & can turn objects into procs/blocks by calling the to_proc method upon the object. For example:
p ['hello', 'world'].map(&:reverse) # => ["olleh", "dlrow"]
Enumerable#map usually takes a block instead of an argument, but & calls Symbol#to_proc and generates a special proc object for the reverse method. This proc becomes the block for the map and thereby reverses the strings in the array.
You could, therefore, 'override' the & unary operator (not to be confused by the equivalent binary operator!) by defining to_proc on an object, with the only restriction being that you must return a Proc object for things to behave. You'll see an example of this later on.
* and splatting
There's a lot of magic to splatting but in short, * can be considered to be a unary operator that will 'explode' an array or an object that implements to_a and returns an array.
To override the unary * (and not the binary * - as in 20 * 32), then, you can define a to_a method and return an array. The array you return, however, will face further consequences thanks to *'s typical behavior!
A Full Example for Ruby 1.8 and Ruby 1.9
We've reached the end of our quick tour through Ruby's unary operators, so I wanted to provide an example that shows how to override (or partially override) them that should stand as its own documentation:
class MagicString < String
def +@
upcase
end
def -@
downcase
end
def ~
# Do a ROT13 transformation - http://en.wikipedia.org/wiki/ROT13
tr 'A-Za-z', 'N-ZA-Mn-za-m'
end
def to_proc
Proc.new { self }
end
def to_a
[self.reverse]
end
if RUBY_VERSION > "1.9.0"
eval %{def !
swapcase
end}
end
end
str = MagicString.new("This is my string!")
p +str # => "THIS IS MY STRING!"
p ~str # => "Guvf vf zl fgevat!"
p +~str # => "GUVF VF ZL FGEVAT!"
p %w{a b}.map &str # => ["This is my string!", "This is my string!"]
p *str # => "!gnirts ym si sihT"
if RUBY_VERSION > "1.9.0"
p !str # => "tHIS IS MY STRING!"
p (not str) # => "tHIS IS MY STRING!"
p !(~str) # => "gUVF VF ZL FGEVAT!"
end
It's almost a cheat sheet of unary operators :-)
A Further Example: The TestRocket
TestRocket is a tiny testing library I built for fun a few months ago. It leans heavily on unary operators. For example, you can write tests like this:
+-> { Die.new(2) }
--> { raise }
+-> { 2 + 2 == 4 }
# These two tests will deliberately fail
+-> { raise }
--> { true }
# A 'pending' test
~-> { "this is a pending test" }
# A description
!-> { "use this for descriptive output and to separate your test parts" }
The -> { } sections are just Ruby 1.9 style 'stabby lambdas' but I've (with assistance from Christoph Grabo) added unary methods to them so that you can prefix +, -, ~, or ! to get different behaviors.
Hopefully you can come up with some more useful application for unary methods on your own objects, of course!
more »
Screencast: Coding Conway’s Game of Life in Ruby the TDD Way with RSpec »
Created at: 02.11.2011 02:25, source: Ruby Inside, tagged: Miscellaneous Tutorials
Recently, there have been many screencasts of people coding things in real time. Yesterday, Ryan Bigg released a video of him implementing Conway's Game of Life from scratch by reading through the 'rules' and then using RSpec to take a test driven approach to fleshing out the functionality.
Ryan is a Ruby Hero and technical writer best known for being co-author of the recently released Rails 3 in Action (along with Yehuda Katz) which I'll be reviewing soon for Ruby Inside. But Ryan's also been getting into doing a little screencasting:
If you can't see the video above, view it directly on Vimeo here.
Ryan's technique is just one of many legitimate approaches but many of you will find something to pick up from this, especially if you're not familiar with test driven development or, perhaps, RSpec. If you're already working on koans non-stop and consider yourself well versed in the ways of TDD, you might want to skip it.
The only downside is that Ryan focuses entirely on the logic without doing a live render of the game board to see his work in action, though this was the right rational choice given the time limit. That would make a good separate project to follow on with, though, if you fancy a little challenge, but be careful to not couple the game logic tightly to any interface you choose to try.
more »
What Ruby’s ||= (Double Pipe / Or Equals) Really Does »
Created at: 18.10.2011 04:37, source: Ruby Inside, tagged: Tutorials
In Rubyists Already Use Monadic Patterns, Dave Fayram made a passing reference to using ||= to set a variable's value if its value were 'Nothing' (false or nil in Ruby). The resulting Reddit quickly picked up on his definition (which was fixed later) and argued about ||='s true meaning which isn't as obvious as many Rubyists think. This spread to Freenode's awesome #ruby-lang IRC channel where I picked it up.
Abstract (or the TLDR Version)
A common misconception is that a ||= b is equivalent to a = a || b, but it behaves like a || a = b
In a = a || b, a is set to something by the statement on every run, whereas with a || a = b, a is only set if a is logically false (i.e. if it's nil or false) because || is 'short circuiting'. That is, if the left hand side of the || comparison is true, there's no need to check the right hand side.
The Common Misconception
a ||= b being equivalent to a = a || b is a popular interpretation for two reasons:
- If
aandbare both local variables,a = a || bis a short and natural reflection of the outcome. - Other operators like
+=and-=do operate this way (and this standard dates back to C), e.g.:a += bis equivalent toa = a + b
Do not confuse [op]= with anything related to ||= or &&=. They're entirely different ideas and are implemented entirely different[ly].
Evan Phoenix (of Rubinius fame)
What's happening then, if not a = a || b?
A Starter for One
Here's a simple example of using a ||= b:
a = nil
b = 20
a ||= b
a # => 20
In this case, a ||= b seems to behave like a = a || b. As mentioned earlier, this is entirely due to a and b both being local variables.
Full Demonstration for Hashes and Arrays
Let's try something more complicated:
h = {}
def h.[]=(k, v)
puts "Setting hash key #{k} with #{v.inspect}"
super
end
# 1. The standard ||= approach
h[:x] ||= 10
h[:x] ||= 20
# 2. The a = a || b approach
h[:y] = h[:y] || 10
h[:y] = h[:y] || 20
# 3. The a || a = b approach
h[:z] || h[:z] = 10
h[:z] || h[:z] = 20
The output:
Setting hash key x with 10 Setting hash key y with 10 Setting hash key y with 10 Setting hash key z with 10
Note that in the first case, using ||=, the hash key's value is only set once. Once it becomes logically truthful (i.e. anything other than nil or false), h[:x] is no longer assigned any new values, not even itself.
The second case, using the a = a || b approach, does result in two assignments (of the same value). The value remains 10 but the syntax forces h[:y] to assign itself as a value again.
In the last case, the behavior is the same as in the first case, demonstrating that a || a = b is a more realistic notation.
Note: Exactly the same result occurs if we switch the hash for an array and the keys for integers.
Full Demonstration for Getter/Setter Methods
A similar outcome occurs if we're referring to objects with getter/setter methods (which you may call accessors):
class MyClass
attr_reader :val
def val=(val)
puts "Setting val to #{val.inspect}"
@val = val
end
end
# 1. The standard ||= approach
obj = MyClass.new
obj.val ||= 'a'
obj.val ||= 'b'
# 2. The a = a || b approach
obj = MyClass.new
obj.val = obj.val || 'c'
obj.val = obj.val || 'd'
# 3. The a || a = b approach
obj = MyClass.new
obj.val || obj.val = 'e'
obj.val || obj.val = 'f'
And the output shows off similar behavior to the hash and array example:
Setting val to "a" Setting val to "c" Setting val to "c" Setting val to "e"
Default Hash Values: A Sneaky Edge Case?
Our travels don't end there though. Back in 2008, David Black noticed an edge case with hashes that have default values. If you follow the logic above to the letter, this case will not surprise you, although from a pragmatic point of view, it's curious.
Let's take a look:
hsh = Hash.new('default')
hsh[:x] # => 'default'
# 1. The standard ||= approach
hsh[:x] ||= 10
p hsh # => {}
# 2. The a = a || b approach
hsh[:y] = hsh[:y] || 10
p hsh # {:y=>"default"}
# 3. The a || a = b approach
hsh[:z] || hsh[:z] = 10
p hsh # {:y=>"default"}
Hashes with default values act in an.. interesting way, depending on your point of view. Merely accessing a value doesn't mean that the value is reified (made concrete) in the hash itself. The reason for this is that you can assign Procs to a hash's default_proc in order to perform calculations (or even to set values) when an unset key is accessed. It would be undesirable to avoid this behavior merely because a key was accessed earlier on.
Again, we note that the a || a = b-style approach gives the result closest to the reality of ||=.
describe "Conditional operator assignment 'obj.meth op= expr'" do
it "is equivalent to 'obj.meth op obj.meth = expr'" do
RubySpec's variables_spec file
Further Reading
This appears to have been a popular discussion point in Rubyland over the years, so I would be remiss not to include links to some of the best references:
- x ||= y, Redux by Rick DeNatale.
- The Reddit discussion about Dave Fayram's post
- comp.lang.ruby: Please explain nuances of ||=
- comp.lang.ruby: The definitive list of ||= (OR Equal) threads and pages
- rubyonrails-talk: What does "||=" mean?
- A short-circuit (||=) edge case
And if this tickled your fancy..
Today I've opened up tickets for the 3rd and 4th runs of my Ruby Reloaded online Ruby course. It's aimed at intermediate developers who want to dig deeper, boost their confidence, and bolster their Ruby skill set. We dig into test driven development (TDD), object oriented design, building a library from scratch, code style, and more. It takes place in November and December.
Check out RubyReloaded.com to learn more about the course, what it involves, and when it runs. There are 24 places on each and about half have gone to waiting list folks so far.
P.S. The coupon code INSIDE will give you a $50 discount to thank you for being a Ruby Inside reader!
more »
Rails for Zombies: An Online Rails Learning Environment »
Created at: 19.11.2010 05:01, source: Ruby Inside, tagged: News Tutorials
Rails for Zombies is an intriguing attempt to teach people how to use Ruby on Rails directly in the Web browser. It comes from Envy Labs (and specifically Gregg Pollack, once of RailsEnvy fame).
The goal of Rails for Zombies is to make the learning process immediately accessible and fun. You're guaranteed to learn quite a bit too as the in-browser development environment frequently tests you and makes you actually do stuff rather than merely read learning material.
As Gregg points out, what you learn through R4Z won't be quite enough for you to build your own version of Twitter (or even Twitter for zombies - arf arf) but it covers enough of the basics to put you in a better position to continue with more traditional learning techniques later.
[suggestion] You know I launched Ruby Weekly, a weekly Ruby e-mail newsletter? Well, last week I launched JavaScript Weekly for all of you JS-heads too! It's been going great and the next issue is out later today.
more »


