basecamp/concerning

Name: concerning

Owner: Basecamp

Description: Bite-sized separation of concerns

Created: 2013-07-02 18:17:27.0

Updated: 2017-05-06 14:24:24.0

Pushed: 2014-02-23 18:45:29.0

Homepage:

Size: 211

Language: Ruby

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Bite-sized separation of concerns

(Note! Module#concerning is included in Rails 4.1. You can still use this library, but it will defer to Active Support's implementation if available.)

We often find ourselves with a medium-sized chunk of behavior that we'd like to extract, but only mix in to a single class.

Extracting a plain old Ruby object to encapsulate it and collaborate or delegate to the original object is often a good choice, but when there's no additional state to encapsulate or we're making DSL-style declarations about the parent class, introducing new collaborators can obfuscate rather than simplify.

The typical route is to just dump everything in a monolithic class, perhaps with a comment, as a least-bad alternative. Using modules in separate files means tedious sifting to get a big-picture view.

Dissatisfying ways to separate small concerns
Using comments:
s Todo
Other todo implementation
...

 Event tracking
s_many :events

fore_create :track_creation
ter_destroy :track_deletion

f self.next_by_event
# ...
d


ivate
def track_creation
  # ...
end

With an inline module:

Noisy syntax.

s Todo
Other todo implementation
...

dule EventTracking
extend ActiveSupport::Concern

included do
  has_many :events
  before_create :track_creation
  after_destroy :track_deletion
end

module ClassMethods
  def next_by_event
    # ...
  end
end

private
  def track_creation
    # ...
  end
d
clude EventTracking

Mix-in noise exiled to its own file:

Once our chunk of behavior starts pushing the scroll-to-understand it boundary, we give in and move it to a separate file. At this size, the overhead feels in good proportion to the size of our extraction, despite diluting our at-a-glance sense of how things really work.

s Todo
Other todo implementation
...

clude TodoEventTracking

Introducing Module#concerning

By quieting the mix-in noise, we arrive at a natural, low-ceremony way to separate bite-sized concerns.

ass Todo
# Other todo implementation
# ...

concerning :EventTracking do
  included do
    has_many :events
    before_create :track_creation
    after_destroy :track_deletion
  end

  class_methods do
    def next_by_event
      # ...
    end
  end

  private
    def track_creation
      # ...
    end
end
d

do.ancestors
=> Todo, Todo::EventTracking, Object

This small step has some wonderful ripple effects. We can


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.