Blog

The tools that are right under your nose

by Jim Gay

I recently had a fantastic experience giving a presentation at RubyConf called The Secrets of the Standard Library. The slides are available and once the video is up I’ll send along a link to that.

There are no secrets in the Standard Library

There are no secrets, of course, because the code is right there for you to read but many developers don’t realize that powerful tools like SimpleDelegator and Forwardable are built into Ruby. There’s no gem to find and install, just require the file you need and you’ve got it. It’s as easy as:

require 'delegate'
class MyWrapper < SimpleDelegator; end

require 'forwardable'
class MyClass
  extend Forwardable
end

My goal in the RubyConf presentation was to show that these tools are available and to describe how they work. Using the tools is one thing, but understanding them is another.

In previous posts we’ve been looking at ways to use SimpleDelegator to handle presentation behaviors and there’s been a bit of Forwardable too. Once you’ve got a clear understanding of them, you can be more creative with their use and build your own tools to make your code more habitable.

I find that implementing my own library can be a great exercise in understanding an existing one. It was fun to write two short lines in an attempt to create SimpleDelegator and Forwardable in what would fit in less than 140 characters:

# My SimpleDelegator
class D;def initialize(o);@o=o;end;
def method_missing(m, *r, &b);@o.send(m,*r,&b);end;end
# My Forwardable
module Fwd;def fwd(a,m,n=m);self.class_eval
"def #{n}(*r,&b);#{a}.__send__(:#{m},*r,&b);end";end;end

Expanding those out with more descriptive names reveals a bit more about what they do:

# My SimpleDelegator
class Delegator
  def initialize(object)
    @object = object
  end
  def method_missing(method, *args, &block)
    @object.send(method, *args, &block)
  end
end
# My Forwardable
module Forward
  def forward(to, method_name, alternative=method_name)
    self.class_eval "
     def #{alternative}(*args, &block)
       #{to}.__send__(:#{method_name},*args, &block)
     end
    "
  end
end

In both my simple implementation and the actual implementation one uses method_missing at run time and the other defines methods at compile time.

Knowing this, and seeing how they work, can help you make decisions about when to use one over the other. Defined methods are faster than method_missing but they require a more rigid structure.

When do you use SimpleDelegator and when do you use Forwardable?

I generally follow these simple rules for choosing which library to select:

  1. Use SimpleDelegator when you either don’t know or don’t care which messages may be sent to your object. This excepts (of course) the methods you define in your wrapper.
  2. Use Forwardable when you know the messages to forward ahead of time.

Both libraries follow the same pattern that a message to one object will be sent along unaffected to the relevant object. But there are times when building your own gives you a better understanding and more control over when errors occurr.

Building your own SimpleDelegator can be tricky. There’s quite a lot of work done for you already to help ensure that your wrapper acts like the wrapped object so do read the code and get familiar with the trade-offs when writing your own.

Errors instead of method_missing

Sometimes you may want more control or restriction on the behavior of objects.

You can build a wrapper with Forwardable, for example, by swapping out the object of concern and instead of everything passing through method_missing, you’ll get a NoMethodError.

Here’s a short example:

class Person
  attr_accessor :name, :color, :number, :email
end
require 'forwardable'
class Wrapper
  extend Forwardable
  delegate [:name, :color, :number] => :person

  attr_accessor :person
end
wrapper = Wrapper.new
wrapper.person = person1
wrapper.name #=> person1 name value
wrapper.person = person2
wrapper.name #=> person2 name value
wrapper.email #=> NoMethodError

A wrapper like this allows us to specify only the methods we want to pass-through and any others that person may have will raise an error.

How have you used these libraries? How do you decide what to use?

What have you built to do similar things?

Last but not least, I recently wrote about undestanding delegation on my blog and how it helped me create the casting gem.

If you enjoyed this post, sign-up for my newsletter below and get more.

Clean Up Your Code

If you liked this post and want more like it, get periodic tips in your inbox by leaving your email address below.

To get more information about cleaning up your objects, classes, and code, then check out Clean Ruby, an ebook which will describe ways to keep your code clean, maintainable, and focused on business value. Make your OOP more obvious, easier to understand, easier to test, and easier to maintain.



Permalink…

Delegation is Everything and Inheritance Does Not Exist

by Jim Gay

Sharing behavior among and between objects requires a balanced decision. Will other objects use this behavior? Which ones? Why? Should I make a new class to handle what I need?

Determining answers led me to dive into exactly what delegation is and inevitably led to more research to get a better understanding of inheritance.

Prefer delegation over inheritance goes the standard advice.

It seems that many developers think about inheritance in terms of classes. Classes define everything about your objects so it must be the only way to handle inheritance. We tend to think about delegation in terms of instances of classes as well.

This mental model mostly works well. But then there’s always someone who points out a seemingly contradictory phrase…

Delegation is Inheritance

Lynn Andrea Stein argued that Delegation is Inheritance in her 1987 OOPSLA paper of the same name. It’s a fantastic read and an important paper in describing the behavior of Object-oriented systems and what the costs and benefits are to different inheritance schemes.

But this title seems to go against a simple mental model of what inheritance and delegation are.

Classes and Prototypes

First and foremost, object-oriented programs tend to have either class-based or prototype-based inheritance.

Sometimes you’ll see comments around the web like this

a problem that Javascript is having is people wanting to force OOP on the language, when fundamentally it’s a prototype-based language

It’s certainly a good thing to understand the way a language was designed, but there is no dichotomy between OOP and prototypes.

Prototypes are an object-oriented paradigm.

Classes are a paradigm which groups objects by type. Classes generate instances whose abilities are defined by their class. This is a rigid approach to sharing behavior and is the one provided in Ruby.

Prototypes on the other hand share behavior among individual objects. An object’s prototype defines behaviors that may be used on the object itself.

Perhaps a problem that people see in JS development is instead forcing a class-based paradigm on their programs. Perhaps not. I’m not venturing into that debate but recognize that prototypes are OO.

Inheritance Through Delegation

Many (most?) OO programmers are familiar with class-based inheritance systems.

You create a new instance of Thing and that thing instance has all of the abilities defined in its class. This concept is easy to grasp.

Prototype-based inheritance, however, seems much more complex. In order to understand the behavior of one object you also need to understand the behavior provided by its prototype which is just another object. A prototype doesn’t necessarily act as an umbrella of classification like classes.

It’s harder to think in generalizations outside of a class system. The type of an object is a simple mental model but with prototypes, the possibilities are myriad.

But getting back to the point of this section, class-based inheritance uses delegation to share behavior. A message sent to the instance thing is delegated to the class Thing. All of the behaviors are defined in the class, but self is bound to the object that received the message. The behavior is evaluated in the context of the object. That is: self refers to the instance, not the class (where the behavior is defined).

class Thing
  def hello
    self.inspect
  end
end

thing = Thing.new
thing.hello # <-- delegation to its class which defines the behavior

In a case where two objects exist in a prototype-based system, the same rules apply. The keyword self is bound to the object that received the message and any delegated behavior is defined in another object.

Ruby delegates through classes and as a result caches its methods based upon the classes of objects. This class-based approach means that adding new behavior to an object leads to the cache being cleared because as an instance of a particular class the object’s behavior changes and needs to be reflected in the method lookup (defined by its class). Charlie Somerville has a great rundown of things that clear Ruby’s method cache.

Our class-colored lenses skew our understanding of delegation.

Inheritance Does Not Exist

This brings me around to why reading Stein’s argument about delegation being inheritance is important. Most (or maybe just many) programmers seem to misunderstand what delegation is.

Stein’s paper made the argument that delegation is inheritance. Her paper is based upon the definition of delegation citing Henry Lieberman’s 1986 paper.

Lynn Stein was recently very helpful to me and suggested that the original understanding of delegation may have come from “Delegation in Message Passing Proceedings of First International Conference on Distributed Systems Huntsville, AL. October 1979”. Alas, I can’t find that paper online but it is related to the application of the Actor pattern by Carl Hewitt, Beppe Attardi, and Henry Lieberman.

Stein’s work was built against the understanding that delegation has a specific meaning. When methods are delegated, they are bound to the object that received the message. The self or this keywords (depending on the language) refer to the original object that received the message.

Many commenters on my delegation article (and on other forums) claimed that the “delegation” term has changed meaning over the years. Lieberman, critics say, may have coined the term but he doesn’t own the meaning.

Some have argued that delegation no longer means what Lieberman, Stein, and other OO pioneers meant. If this is true and delegation means 2 objects forwarding messages, and if delegation is inheritance, then effectively every object sending a message is inheritance. Either that or inheritance does not exist.

Why Care?

I’ve been working around the limitations of implementing DCI in Ruby and the behavior of objects is a central concern.

In DCI our bare data objects gain behavior inside a context relevant to some business goal. Typically this is either explained through the use of extend to add a module to an object’s inheritance lookup:

thing.extend(SomeModule)
thing.method_from_module

The problem in Ruby is that the object’s inheritance tree remains the same for the life of the object.

# Before
thing.singleton_class.ancestors #=> [Thing, Object, Kernel, BasicObject]
thing.extend(SomeModule)
# After
thing.singleton_class.ancestors #=> [SomeModule, Thing, Object, Kernel, BasicObject]

The thing object is forever tied to it’s new set of ancestors. This may affect your program if you expect your object to lose behavior after executing some procedure inside a DCI context.

There are projects which hack Ruby to add unextend or other like methods, but they are additions to Ruby typically only in one interpreter (like MRI).

What Can Ruby Do?

A new feature of Ruby 2.0 is exciting in the abilities we’ll have to build libraries that aid in delegation.

Methods defined in modules may now be bound to objects regardless of their class ancestry.

SomeModule.instance_method(:method_from_module).bind(thing).call

That code is a mouthful, but it shows (in Ruby 2.0) that we can add behavior to objects without extending them.

If we want to implement a delegation technique we could hide all this inside a method.

def delegate(method_name, mod)
  mod.instance_method(method_name).bind(self).call
end

This is an approach I built into casting, a gem that helps add behavior to objects, preserves the binding of self inside shared methods and leaves the object in it’s original state.

It’s easy to use, but it takes a different view of what delegation is compared to how most Ruby developers seem to think. The delegated method here will preserve the self reference to the thing object and behavior is added without extending the object.

class Thing
  include Casting::Client
end

thing.delegate('some_method', SomeModule)

It’s a work in progress and has given me a great reason to explore what Ruby can and can’t do.

The Best of Both Worlds

Stein’s paper suggested that a hybrid system of both class-based and prototype-based inheritance would provide both rigidity and flexibility when needed.

As I’ve worked with my code more and researched more for Clean Ruby I’ve had the desire for a hybrid system. Stein’s words ring true:

In order to take full advantage of the potential of such a system, objects must be treated simply as objects, rather than as classes or instances.

Indeed, DCI requires a system where an object gains and loses behavior based upon the context. The behaviors are localized to the context and a hybrid system like the one Stein described would benefit from the advancement of DCI.

This is a challenge to implement in Ruby but I’ll be working more on casting in the future.

For now, it’s useful to consider the contextual behavior of our objects and think less about the classes that define them and more about the message passing among them.

Focus on the behavior of your system first, use delegation and worry about classes later.

Clean Up Your Code

If you liked this post and want more like it, get periodic tips in your inbox by leaving your email address below.

To get more information about cleaning up your objects, classes, and code, then check out Clean Ruby, an ebook which will describe ways to keep your code clean, maintainable, and focused on business value. Make your OOP more obvious, easier to understand, easier to test, and easier to maintain.



Permalink…

How abstractions encourage good thinking

by Jim Gay

Many times, as developers, we grow our code in ways we don’t intend. We live with quick decisions a little too long and end up with a problem where, well, we don’t see the problem. With too much of this, our code becomes our unkempt bedroom or messy desk.

Working against your brain

A few years ago I saw an excellent presentation at Rocky Mountain Ruby by Michael Feathers about a phenomenon he called “code blindness.” In that keynote he raised the point that despite the fact developers may know how to, or know why our code should be structured differently, we become used to seeing things the way they are and no longer recognize real or potential problems. We become blind to it.

This type of behavior is a result of how our brains react to visual clutter. As we add more information, more objects, and more variablity to the environment we’re creating, our brains will dampen the signals from each part and hide their influences on our attention.

The dampening of each stimulus is a way we cope with too much information. The NIH released a news advisory in 1998 which explained how our brains can counterbalance the dampening effect with focused attention. So what exactly does this mean and how does it apply to programming?

Read the NIH advisory here.

Our programming languages are merely ways of representing concepts. Our brains translate characters to representations of things, to describe iteration, to define decisions and outcomes, and more. The more variation and number of concepts we require our brains to translate, the harder it becomes to maintain focused understanding of any individual concept.

This, of course, leads to the development of ideas such as separation of concerns, the single responsibility principle, and others in which we aim to remove visual clutter form our code and reduce the cognitive load on our brains required to translate stimuli into ideas.

By dampening the effect of stimuli, our brains are able to better focus on the immediate task. The studies at the NIH revealed that by placing effort to focus on a particular aspect of our environments we are able to counteract the dampening feature of our brains. This makes quite a bit of sense: pay attention to something and you’re more likely to notice it. But as the NIH points out that while we may only partially cancel-out the effects of nearby stimuli, the amount of the attention required increased in tandem with the amount of visual clutter.

Living with complexity and clutter in our code is often a way we decide to get work done faster now and come up with a better solution later. Unfortunately it is also a decision to create an environment where we’ll have to work harder in the future to focus on the right thing.

Working with your brain

The more we have in our environments demanding attention, the more our brains will dampen our attention to them.

Abstractions, such as the presenters we’ve reviewed in previous articles, are a way we can remove visual clutter and unnecessary stimuli. Separating our programs into layers of responsibility is a way of working with our brains to ensure they’ll only need to place just enough effort required to maintain focus and understanding of a particular concept.

The act of building these layers in our programs is how we make decisions to work with our brains' ability to manage focus and prevent the dampening effect from slowing down our work.

This introduces to our program our idea of habitable code. What we consider to be a place where our brains will function well will be expressed in our program code. Often, the place I find the most trouble is with view templates. As a result I work to treat these as much as possible like configuration where logic and number of distinct objects are kept to a minimum.

Transformations of data are often a place where confusing details can cause us to filter out valuable concepts from our minds. View templates which contain multiple objects, transformations of data, control structures such as if/else/unless blocks or iteration are a source of clutter.

Visual clutter can appear all over or merely in a single line.

link_to timeslot.in_time_zone(@timezone).strftime("%l:%M%p"), 
  new_profile_appointments_calendar_event_path(@calendar.profile, @calendar, 
  :event_slot_id => event_id, :timezone_name => @timezone.name), 
  :class => "open", rel: 'nofollow'

When we write code we create the environment in which our brains must function and react. Often, we end up creating these cognitive barriers in our view templates like this. Fortunately, we’re able to simplify them with techniques like pushing complexity into a presenter layer.

If you review the code sample above, you’ll need to spend quite a bit of time, far more than you should, just to understand what will be output.

It’s important to make decisions to remove the parts unimportant to us. The abstractions which we create can remove as much information as we decide. Leaving parts for our brains to compose can be a feature:

link_to time_display, new_event_path, class: "open", rel: "nofollow"

Or creating a small footprint to handle a concept at a higher level allows us to remove visual clutter and removes the need to compose parts.

presenter.new_event_link(class: "open", rel: "nofollow")

These sample bits of code show no implementation, but the great thing about programming is that we get to choose. The choices we make might work with our brains or might work against them. We can push away noisy details like which timezone to use for formatting and how how to

Our divide and conquer approach with abstraction layers helps us to filter out noise from signal. Of course, with too much abstraction we may become mired in the noise created by divided ideas but we get to decide and experience what fits best.

Work with your brain and consider what ideas belong in which places. Write the code you wish to have.

Clean Up Your Code

If you liked this post and want more like it, get periodic tips in your inbox by leaving your email address below.

To get more information about cleaning up your objects, classes, and code, then check out Clean Ruby, an ebook which will describe ways to keep your code clean, maintainable, and focused on business value. Make your OOP more obvious, easier to understand, easier to test, and easier to maintain.



Permalink…

Unleash the Secrets of the Standard Library

by Jim Gay

RubyConf 2013 was a fantastic experience and I was fortunate enough to give a presentation about learning from the tools in the Standard Library. The presentation was recorded and will be online soon.

While the slides alone don’t reveal the value from my presentation, I encouraged the audience to read the ruby source and discover what the standard library has to offer. We looked at how delegate.rb and forwardable.rb can help solve problems and how they are implemented. There’s plenty of tricks to pick up in there.

I had a great time having a chat on Ruby5 too.

Update:

My presentation was posted by Confreaks:

Permalink…

Easy Metaprogramming For Making Your Code Habitable

by Jim Gay

In my last message, I wrote about simplifying the code you write by using the Forwardable library. It allows you to represent ideas with succinct code:

delegate [:sanitize, :link_to, :paginate] => :view

In one short line we’re able to show that certain messages and any arguments will be forwarded to another object.

The Presenter class we’ve been working with also has convenient methods created based upon the name of any inherited classes. A UserPresenter will have user and user= methods mapped to __getobj__ and __setobj__ by an easy to follow convention of choosing a name that makes sense.

These are ways that I’ve found in my own code to make it more habitable for me and my team. With as little effort as possible, we should feel at home understanding and changing behavior of the system.

Make your own shortcuts

I have had projects where data would be displayed to a user but may have come from multiple different sources. A user record might be imported from a third-party system and have data that needs to be updated. Or a person in a system might have one or more public profiles from which we need to choose to display information.

If an updated profile has good information we want to show that, otherwise, we’ll show some other imperfect information.

Here’s an example of an approach I took recently. I needed a way to specify that my data should first come from a profile and then fallback to the user record if no data was available. This is what it looked like:

class UserPresenter < ::Presenter
  delegate [:profile] => :user
  maybe :full_name, :address, :from => :profile
end

I went with the name maybe but you might find that something else is clearer for you.

Here’s how I made it work:

class Presenter < SimpleDelegator
  def self.maybe(*names)
    options = names.last.is_a?(Hash) ? names.pop : {}
    from = options.fetch(:from)
    class_eval names.map{|name|
      %{
        def #{name}
          #{from}.public_send(:#{name}) || __getobj__.public_send(:#{name})
        end
      }
    }.join
  end
end

This creates a maybe class method which looks for a collection of method names and an hash in which it expects to find :from. Next it opens up the class (which would be UserPresenter in this case) with class_eval and defines methods based upon the provided string.

The methods are simple and they are equivalent to something like this:

class UserPresenter < ::Presenter
  def full_name
    profile.full_name || user.full_name
  end
end 

Although the full methods are short, using this technique allowed me to simplify the code necessary to handle the concept. Additionally, as I needed, I was able to make changes where a blank, but non-nil value wasn’t considered a valid.

Changing the behavior to avoid nil and blank strings was easy:

def #{name}
   value = #{from}.public_send(:#{name})
   (!value.nil? && value != '' && value) || __getobj__.public_send(:#{name})
end

Or if you have ActiveSupport:

def #{name}
   #{from}.public_send(:#{name}).presence  || __getobj__.public_send(:#{name})
end

Beware of indirection

This code made sense in my project, but for yours it might not. If I were to only use this for the full_name and address methods then I’d probably be making my project less habitable. A layer of indirection, especially when woven through metaprogramming, can be a painful stumbling block to understanding the code later. Be careful to think about how or if you need to apply code for a pattern like this.

Get more tips like this by signing up for my newsletter below.

Clean Up Your Code

If you liked this post and want more like it, get periodic tips in your inbox by leaving your email address below.

To get more information about cleaning up your objects, classes, and code, then check out Clean Ruby, an ebook which will describe ways to keep your code clean, maintainable, and focused on business value. Make your OOP more obvious, easier to understand, easier to test, and easier to maintain.



Permalink…

What to code when you know what you want

by Jim Gay

My last few posts have built up a simple wrapper class that helps to add behavior to an object when we’re displaying information to our users.

  1. Ruby delegate.rb Secrets
  2. The easiest way to handle displaying bad data
  3. Simplify your code with your own conventions
  4. Formatting collections of objects with SimpleDelegator
  5. How to make your code imply responsibilities

We’ve been using SimpleDelegator which uses method_missing to do its magic. But there’s another way of forwarding messages with the standard library Forwardable.

In our presenters, we’ve been wrapping a main object and a view to handle concerns for the display but there are certain features that we don’t want to augment with our wrapper. In Rails we have methods like link_to which help us to create links in our display, and in previous code I showed how we used the view reference in our presenters to handle sanitizing content:

class Presenter < SimpleDelegator
  def sanitize(*args)
    @view.sanitize(*args)
  end
end
class UserPresenter < Presenter
  def bio_html
    sanitize(user.bio)
  end
end

This sanitize method highlights an aspect of handling the behavior of our presenters: sometimes we know exactly what we want to happen, other times we don’t know or don’t care.

Use shortcuts for forwarding when you know what you want

When building my presenters, we knew that we needed to have the view handle sanitization because it was built into the framework. But writing methods every time we wanted to send a message to the view is cumbersome. This is how we made it even easier:

require 'forwardable'
require 'delegate'
class Presenter < SimpleDelegator
  extend Forwardable
  delegate [:sanitize, :link_to, :paginate] => :view
end

With this simple change, we can use all of these specified methods inside our presenters and they’ll automatically be handled by the specified object, the view.

When this Presenter class is loaded, these methods (sanitize, link_to, and paginate) will be generated for us. They’ll define the named methods and automatically pass along any arguments.

This allows us to create simpler classes without the need to create method definition blocks ourselves and our other methods end up looking like this:

class ProfilePresenter < ::Presenter
  def social_media_link(options={})
    link_to('Tooter', tooter_url, options)
  end
end

The access to link_to is implicit: we expect it to be there already. Implicit behavior can be dangerous in that it requires that anyone working with the code know to expect the behavior. Your development team should be aware of the structure of your presenter classes and understand that these methods will automatically be forwarded to the view. But this is all a part of finding patterns in your code.

Rails-flavored forwarding

If you’re using Rails, you don’t need to use Forwardable because every class in your program will already have a delegate method defined by ActiveSupport.

The syntax is similarly easy:

require 'delegate'
class Presenter < SimpleDelegator
  delegate :sanitize, :link_to, :paginate, :to => :view
end

Your code will be more succinct when you use shortcuts provided by Forwardable and other libraries. SimpleDelegator allows us to create objects which act as a pass-through filter for behavior. Because of method_missing, we can treat our wrapper like a replacement for another object but with Forwardable, we must specify our intentions when we design the class.

Try it out and let me know how you handle managing behavior among objects in your wrappers. Everyone on my Clean Ruby mailing list gets regular tips like this. Signup below.

Clean Up Your Code

If you liked this post and want more like it, get periodic tips in your inbox by leaving your email address below.

To get more information about cleaning up your objects, classes, and code, then check out Clean Ruby, an ebook which will describe ways to keep your code clean, maintainable, and focused on business value. Make your OOP more obvious, easier to understand, easier to test, and easier to maintain.



Permalink…

1999 - 2014 © Saturn Flyer LLC 2321 S. Buchanan St. Arlington, VA 22206

Call Jim Gay at 571 403 0338