Delegation and the laws of demeter

After reading about delegation and the laws of demeter I have been
attempting to use the “delegate” method in Rails to avoid situations
where I would have to write…

@account.account_holder.name

and risk a NoMethodError if @account.account_holder is nil

Delegate looked ideal as it allows me to specify
@account.account_holder_name and delegate that to AccountHolder and
alias :name to :account_holder_name.

However, it seems by this point to have already become slighty ugly
code (delegating and then aliasing methods) and to top it all if it
appears that delegate doesn’t return nil, but still raises an
exception.

As the laws of demeter seem quite sound and a good principal to
follow, is there any reason that we shouldn’t be using “delegate”? and
if we are supposed to use it why doesn’t it return something safe like
nil? (or does it just need a patch?)

Are there any other techniques I can use to avoid having to traverse
potentially nil relationships to retrieve attributes?

Refs:
http://caboo.se/doc/classes/Module.html#M003481
http://quotedprintable.com/articles/2006/12/22/delegation-and-demeter-in-rails
http://brian.maybeyoureinsane.net/blog/2006/12/15/law-of-demeter-or-how-to-avoid-coding-yourself-into-a-corner-in-rails/

David S. wrote:

After reading about delegation and the laws of demeter I have been
attempting to use the “delegate” method in Rails to avoid situations
where I would have to write…

@account.account_holder.name

and risk a NoMethodError if @account.account_holder is nil

Delegate looked ideal as it allows me to specify
@account.account_holder_name and delegate that to AccountHolder and
alias :name to :account_holder_name.

However, it seems by this point to have already become slighty ugly
code (delegating and then aliasing methods) and to top it all if it
appears that delegate doesn’t return nil, but still raises an
exception.

As the laws of demeter seem quite sound and a good principal to
follow, is there any reason that we shouldn’t be using “delegate”? and
if we are supposed to use it why doesn’t it return something safe like
nil? (or does it just need a patch?)

Are there any other techniques I can use to avoid having to traverse
potentially nil relationships to retrieve attributes?

Refs:
http://caboo.se/doc/classes/Module.html#M003481
http://quotedprintable.com/articles/2006/12/22/delegation-and-demeter-in-rails
http://brian.maybeyoureinsane.net/blog/2006/12/15/law-of-demeter-or-how-to-avoid-coding-yourself-into-a-corner-in-rails/

Hi, please try the Law of Demeter gem

Its a DRY way to apply Law of Demeter with demeter gem

http://gemcutter.org/gems/demeter

David S. wrote:

After reading about delegation and the laws of demeter I have been
attempting to use the “delegate” method in Rails to avoid situations
where I would have to write…

@account.account_holder.name

After reading about the Law of Demeter myself, I’ve come to the
conclusion that some laws are made to be broken. :slight_smile:

and risk a NoMethodError if @account.account_holder is nil

Delegate looked ideal as it allows me to specify
@account.account_holder_name and delegate that to AccountHolder and
alias :name to :account_holder_name.

Delegation is a pattern I actually like, and I do see that it could be
useful in helping with the LoD issue. However, if in cases where I feel
that I’m adding complexity for no other purpose than to follow some
“law” just doesn’t feel right to me. I think I would prefer simply
checking using a “design by contract” style of programming to make sure
that the nil case is not allowed.

However, it seems by this point to have already become slighty ugly
code (delegating and then aliasing methods) and to top it all if it
appears that delegate doesn’t return nil, but still raises an
exception.

My point exactly.

As the laws of demeter seem quite sound and a good principal to
follow, is there any reason that we shouldn’t be using “delegate”? and
if we are supposed to use it why doesn’t it return something safe like
nil? (or does it just need a patch?)

I’m not at all saying that the LoD isn’t sound. However, I tend toward
the simplest solution that solves the problem at hand. If the pragmatic
solution happens to break some theoretically sound principal, then so be
it.

Are there any other techniques I can use to avoid having to traverse
potentially nil relationships to retrieve attributes?

Yes, “Design by Contract” can be one alternative. If you are depending
on internal structure for your objects then prepare for that with a
“contract.” I’m not saying that this has to be formal. The “contract”
could be as simple as checking for nil.

Example:
@account.account_holder.name if @account && @account.account_holder

Besides that LoD seems a little unclear to me. For example, does the
following break LoD?

account_holder = @account.account_holder
name = account_holder.name

While producing the same result as name = @account.account_holder.name,
it does not seem to directly break LoD. This does, however, exhibit the
same problem as the code breaking LoD.

Are there any other techniques I can use to avoid having to traverse
potentially nil relationships to retrieve attributes?

I didn’t mention this in my previous post because it is off-topic in the
Ruby world. However, there is another technique employed to avoid the
nil problem you described. This is a solution provided by Objective-C
and it is a simple and powerful (yet sometimes dangerous) solution.

With no further ado here it is: What if nil accepted any message without
error?

name = [[account accountHolder] name];

This code would not break due to nil objects. If account, or the object
returned by [account accountHolder] were nil then name would be nil and
there would be no errors, nor exceptions thrown.

This code does not follow LoD, yet does not present the nil problem
described in your original post.

It does, however, present other LoD related issues. For example, what if
account does not respond to accountHolder, or if the object returned by
[account accountHolder] does not respond to name?

The common technique most often employed in this case is again related
to “Design by Contract.” One would check to make sure [account
respondsTo:@selector(accountHolder)] and [[account accountHolder]
respondsTo:@selector(name)].

This contract would be needed in cases where static type checking is not
used or not effective. While, static type checking can prevent many of
these problems, it does not solve them all. Not even in a purely
statically typed language such as Java.

Marnen Laibow-Koser wrote:

If I understand you correctly, you are using “Design by Contract” in a
sense almost exactly opposite to the sense in which Meyer defined the
term. The point of Meyer’s DBC is that you don’t have to do explicit
checking, because the contract mechanism guarantees it.

Yes, you are correct. I was using the term very loosely. In a true
“Design by Contract” language, such as Eiffel, the checking is still
there, but has been moved into the DbC mechanism provided by the
language. This would eliminate the need to do the checking in the actual
method body. However, the contract still must be defined by the
developer and so is still code. It’s just in a different place.

Robert W. wrote:

Are there any other techniques I can use to avoid having to traverse
potentially nil relationships to retrieve attributes?

I didn’t mention this in my previous post because it is off-topic in the
Ruby world. However, there is another technique employed to avoid the
nil problem you described. This is a solution provided by Objective-C
and it is a simple and powerful (yet sometimes dangerous) solution.

With no further ado here it is: What if nil accepted any message without
error?

name = [[account accountHolder] name];

I understand that nil in Smalltalk acts this way (which is probably
where Obj-C got it), and I have occasionally used a custom QuietNil
class for just this purpose.

[…]

The common technique most often employed in this case is again related
to “Design by Contract.” One would check to make sure [account
respondsTo:@selector(accountHolder)] and [[account accountHolder]
respondsTo:@selector(name)].

If I understand you correctly, you are using “Design by Contract” in a
sense almost exactly opposite to the sense in which Meyer defined the
term. The point of Meyer’s DBC is that you don’t have to do explicit
checking, because the contract mechanism guarantees it.

This contract would be needed in cases where static type checking is not
used or not effective. While, static type checking can prevent many of
these problems, it does not solve them all. Not even in a purely
statically typed language such as Java.

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]