Online Book Reader

Home Category

Beyond Java - Bruce Tate [59]

By Root 684 0
together a set of methods that many classes may need to use.

Look at this contrived little example. To build the friendliest possible application, you may want to build a mixin to greet any object by name. You'd code it like this:

irb(main):021:0> module Greetable

irb(main):022:1> def greet

irb(main):023:2> puts "Hello, " + self.name

irb(main):024:2> end

irb(main):025:1> end

=> nil

Then, you can include this code in a class called Person:

irb(main):011:0> class Person

irb(main):012:1> include Greetable

irb(main):013:1> def initialize(name, age)

irb(main):014:2> @name=name

irb(main):015:2> @age=age

irb(main):016:2> end

irb(main):017:1> attr_reader :name

irb(main):018:1> end

=> nil

You can use this code in Person:

irb(main):039:0> person=Person.new("Bruce",40)

=> #

irb(main):040:0> person.greet

Hello, Bruce

=> nil

While mixins seem interesting, this code probably smells wrong to you. Unless you could better integrate the Person methods in the mixin, it's just a recipe to make bad design decisions: you can include stuff that doesn't really have anything to do with Person into Person. But it's more powerful than that. You can separate an aspect, or a capability, into a mixin. What makes mixins so powerful is this: you can also access Person's class methods in your module. In fact, we used Person.name, in the module, before we had even defined Person. If it sounds confusing, just look at the following module. inspect is a class method that puts the contents of an object in string form:

irb(main):147:0> module Reversible

irb(main):148:1> def inspect

irb(main):149:2> super.reverse

irb(main):150:2> end

irb(main):151:1> end

=> nil

Note that you haven't defined a class yet, but you're still using the inspect class method. That may seem strange until you include the module in the Calculator class that we made before:

irb(main):152:0> class Person

irb(main):153:1> include Reversible

irb(main):154:1> end

=> Person

Now you've included the module, and it has a class. It's now a mixin. You can call any new instance methods that it defines. It will assume the class that you add it to. Look at what happens when you instantiate it:

irb(main):155:0> p=Person.new("Bruce", 40)

=> >"ecurB"=eman@ ,04=ega@ 0711c82x0:nosreP<#

irb actually calls inspect when you instantiate an object. Did you see the garbled line at the bottom? It's actually "Person:0x28c1170 @age=40, @name=\"Bruce\" in reverse. That's impressive. Now, you can add a mixin that can inspect the class, and integrate the most intimate details of the class into the mixin. And you can do all of this integration before a class even exists. I can use mixins for things like security or persistence. Java developers often resort to AOP to get the capability of mixins.

Interceptors


I've said that Java framework developers these days place an ever-increasing value on techniques that change the behavior of an existing class, without changing its code. One such technique is method interception . JBoss and Spring use method interception to attach arbitrary services to a POJO. With Ruby, interception is easy. You simply take a method, rename it, and put another method in its place (see Figure 6-2).

For example, let's say that my friend, Dave Thomas, asks me to watch his laptop for a few minutes before his big Ruby presentation. I could go to his Ruby shell and enter this little gem based on an example from his book,

Figure 6-2. In Ruby, to do method interception, you simply rename and replace a method, with the new implementation calling the old

Programming Ruby (Pragmatic Bookshelf). This version intercepts new, as you can see in Figure 6-2. I simply rename the original and call it from the replacement new. The interceptor will print out a message whenever Ruby creates a new object. Here's how easy it is:

class Class

alias_method :original_new, :new

def new(*args)

result = original_new(*args)

print "Unattended laptop error. "

return result

end

end

And when Dave gets back to teach

Return Main Page Previous Page Next Page

®Online Book Reader