Beyond Java - Bruce Tate [58]
What makes Java limiting to you?
DHH: On an "every language can do anything" level, there's nothing that inherently limits what Java can do, but there's certainly different comfort zones for different languages and people. I can't stand repeating myself. I can't stand a long feedback cycle. I can't stand computing in my head or writing by hand what the compiler should be able to figure out from my intentions.
Java doesn't make me a happy programmer; Ruby fills me with joy. I don't want to work with tools that don't make me happy. So, if that were the only choice, I would pick a different career where I could work with tools that made me happy.
Are Ruby and Rails ready for production web applications?
DHH: Not only ready, but already running. Basecamp, the application that birthed Rails, has been running for more than a year and is widely successful. Upstarts working on the Web 2.0 frontier are picking Ruby on Rails in droves. 43things.com and Odeo.com are just two examples of that.
Classes
Ruby is object-oriented. I've shown you how to use Ruby objects , but not yet how to create one. Let's make a class called Calculator. Create a file called calculator.rb that looks like this:
class Calculator
def initialize
@total=0
end
def add(x)
@total += x
end
def subtract(x)
@total -= x
end
end
You've declared three methods. Ruby will call initialize when it creates a new object, such as this calculator. Notice that initialize defines an instance variable called @total. In Ruby, instance variables start with @, class variables start with @@, and global variable start with $. Now, in irb, you can load the file and use the calculator.
irb(main):005:0> require 'Calculator'
=> true
irb(main):006:0> c=Calculator.new
=> # irb(main):007:0> c.add 100 => 100 irb(main):008:0> c.subtract 40 => 60 And it works, just like you'd expect. Ruby developers take advantage of open classes . I'm going to change the definition of Calculator, but keep in mind that we still have c, an instance of Calculator. I actually open up the definition of the class again like this: irb(main):009:0> class Calculator irb(main):010:1> def reset irb(main):011:2> @total = 0 irb(main):012:2> end irb(main):013:1> end I just added a method called reset. I also could have changed an existing method. irb(main):014:0> c.reset => 0 That's amazing. I changed the class definition of an existing class. That's a useful capability for debugging, iterative programming, and metaprogramming. Ruby also lets you subclass. To subclass, you use the < operator: irb(main):015:0> class IrsCalculator < Calculator irb(main):016:1> def add(x) irb(main):017:2> x = x / 2 if x>0 irb(main):018:2> super irb(main):019:2> end irb(main):020:1> end => nil You can use it, and IrsCalculator will take a little off the top for you: irb(main):027:0> c=IrsCalculator.new => # irb(main):028:0> c.add 100 => 50 These concepts should look familiar to you. Classes package instance data and methods together. An instance of a class is an object. All classes have single parents, and eventually inherit from Object, with the exception of Object: irb(main):031:0> Class.superclass => Module irb(main):032:0> Module.superclass => Object irb(main):033:0> Object.superclass => nil Using Mixins Mixins are not new. Smalltalk supported them back in 1971. Recall that a mixin is an interface with an implementation. That means you can group
To implement a mixin, Ruby uses a concept called a module. A module lets you group together methods and classes. You can't instantiate a module, and a module doesn't stand alone. A module isn't a class, but it does have its own namespace. Modules form the foundation of classes and mixins .