Skip to content

Investigations of various ways of giving an object transient behavior

Notifications You must be signed in to change notification settings

woahdae/transcience

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Strategies for defining temporary behavior

What originally started out as an investigation into the (poorly named) phenomenon dubbed self-schizophrenia in view object wrappers like Draper or Sexy Presenter ended up as a full-on investigation into many aspects of assigning temporary behavior to objects in Ruby.

I already have an affinity for simple inheritance for this purpose after reading Growing Rails, but simple inheritance is limited to use cases where you only need to assign a single operation to a single class.

I also have a dislike for decorators. They seem good on paper, but have some serious suprises once you try using them. They're not the "flexible alternative to subclassing" they're supposed to be. Plus, popular decorator gems have Rails compatibility issues (ex. Rails' view helpers don't play well with wrapped objects, nor with HAML's CSS ID and class helpers).

So, what's a Rails developer left with? Is it best to beat a decorator into submission with metaprogramming tricks? Live with the limitations of derocators? How about #extend at runtime - good in theory, but doesn't it have huge performance issues?

You can just read the summary, and/or dive deeper into the subdirectories. Each one has a README, so you won't have to do much code spelunking.

Summary

If you're using Ruby 2.1 or later, don't avoid #extend for performance reasons. It's now at least as performant as delegation, maybe better, and there is no risk of invalidating your class cache like in earlier versions of Ruby.

If you're using Ruby 2.0 or earlier, favor a delegation strategy and deal with the fallout. You'll need to do things like ex. copy/paste HAML's underscore into your delegators' haml_object_ref method, and other hacks. But it's the best there is, pre-2.1.

Dive Deeper

  • the comparison directory contains many implementations of wrapper objects, and unit tests that assert the various things we want to be true of a wrapper object. Not all the tests pass, since not all strategies provide everything we want. The comparison README summarizes my findings.
  • the avdi directory implements Avdi Grimm's article on delegators with tests. I just wanted to see the issues for myself.
  • the webapp directory implements a Rails app using Draper to see if it suffers from issues with the delegator pattern I've experienced in my own home-grown SimpleDelegator-based presenter implementations. The webapp README has screenshots showing what I found.
  • the extend_perf_test directory follows up on many popular but dated blog posts on the topic of #extend performance. The extend_perf_test README summarizes the results.

About

Investigations of various ways of giving an object transient behavior

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published