Agile Ajax

Save That Duck!

So, while most of you were off celebrating the holidays, Dietrich was off killing a duck, or at least Duck Typing. Personally, I always thought that the goose was the traditional holiday bird.. shows what I know.

Deitrich's argument is that Duck Typing does not allow "Dead Duck Typing", being able to restrict access to part of an object's state or functionality. The classic case here is keeping a display layer from getting at the persistence layer. (Maybe we can call this Stephen Colbert Typing, since you're declaring part of the object as "dead to me"...)

Dietrich closed his post with:

Some will argue this is a Java-ism creeping into Ruby. I say this is just plain old-fashioned good OO design.

Which I think is my cue.

I understand the theoretical argument for having strict (or stricter) access control in a system, and I certainly understand why having small, high cohesion classes is a good thing. My problem is that it's very rare for me to have a practical issue in a system because of loose access control or overly generous interfaces (granted, I've had a good run of working with smart people). On the other side, I commonly find that when I'm writing a program with access control I'd like to do something more flexible with an object, but I can't, because the original writer of the class did not anticipate the usage.

Specifically on the Ruby side, it's actually not hard at all to restrict access to an object. ActiveRecord objects can easily be made read only called before being passed to a view to protect from inadvertent changes.

In the more general case, it's not hard to do something like this, which only allows certain methods of an object to be called:

class ArbitraryProxy

def initialize(object, *methods)
@object = object
@methods = methods
end

def method_missing(method, *args)
if @methods.include? method
return @object.send(method, *args)
end
super
end

end

x = ArbitraryProxy.new("abcd", :size, :gsub)
p x.size
p x.gsub("b", "---")
p x.upcase

This returns:

4
"a---cd"
NoMethodError: undefined method ‘upcase’

The interesting thing is that, by and large, Rails developers don't feel the need to do this. I don't think I've ever seen an authoritative source suggest that it's best practice to make ActiveRecord objects read only before passing them to the view.

There is a Rails plugin called Liquid that enforces the use of proxy objects before being passed to the view. It's not very widely used (in part because creating the proxies is kind of a pain).

I don't see that Ruby and Rails programmers see this issue as a practical problem facing them (it helps that Ruby tends to encourage small classes in other ways). That said, there are clearly cases where you need to be extra careful. Liquid is used as user-facing templating engine for a blog tool, which is clearly a case where you'd want to limit the damage that your template writers can do.

But I see that as the exception, not the rule. Long live the Duck!


Coming Soon: Professional Ruby on Rails -- available in bookstores Mid-Februrary.

Technorati Tags:
, ,

Leave a comment

Powered by WP Hashcash

About Pathfinder

  • We design and build extraordinary applications for companies looking to make the next great idea a reality.
  • learn more

Topics

WordPress

Comments about this site: info@pathf.com