Michael Feathers | 4 Jul 2009 15:04
Picon

East Oriented Code


James Ladd shot me a link to this in twitter the other day, and I think 
it is a great new way of seeing and explaining 'Tell, Don't Ask.'

The gist of it is that if you look at how values move in your code, it's 
better when they move to the right rather than the left:

http://jamesladdcode.com/?p=12

------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/refactoring/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/refactoring/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:refactoring-digest <at> yahoogroups.com 
    mailto:refactoring-fullfeatured <at> yahoogroups.com

<*> To unsubscribe from this group, send an email to:
    refactoring-unsubscribe <at> yahoogroups.com

(Continue reading)

John Carter | 5 Jul 2009 23:50
Picon

Pattern: must_build? return reason.

Here is a little pattern to refactor towards...

So you have a predicate...

# Returns true if I must do "blah" for one of many possible reasons.
def must_blah?
end

So it returns true, but why? Which reason? The poster child case is in
a build script...

   if generated_file.must_rebuild?
      do_something_expensive
   end

For some reason it keeps rebuilding, why?

Change the api slightly...

# Returns a string with the reason I must do "blah", else nil.
def must_rebuild?
end

reason =  generated_file.must_rebuild?
unless reason.nil?
    log reason
    do_something_expensive
end

Nifty.
(Continue reading)

Alan Stokes | 5 Jul 2009 23:58
Picon

Re: Pattern: must_build? return reason.

2009/7/5 John Carter <john.carter <at> tait.co.nz>:
> reason =  generated_file.must_rebuild?
> unless reason.nil?
>    log reason
>    do_something_expensive
> end

I've seen something similar in a couple of contexts - where the reason
needs to be communicated to a person, either via log message or GUI.

What if there's more than one reason? Sometimes you just want the
first, or the most important; sometimes you need all the reasons.

- Alan

------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/refactoring/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/refactoring/join
    (Yahoo! ID required)

<*> To change settings via email:
(Continue reading)

Peter Jaros | 6 Jul 2009 01:10
Picon
Gravatar

Re: Pattern: must_build? return reason.

On Sun, Jul 5, 2009 at 5:50 PM, John Carter<john.carter <at> tait.co.nz> wrote:

> # Returns a string with the reason I must do "blah", else nil.
> def must_rebuild?
> end
>
> reason = generated_file.must_rebuild?

A neat thought, but frankly, this rubs me the wrong way.  I would
never expect a method called #must_rebuild? to return anything but a
boolean.

Why not offer a second method returning the reason?

Peter

------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/refactoring/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/refactoring/join
    (Yahoo! ID required)

(Continue reading)

Adam Sroka | 6 Jul 2009 01:27
Picon
Gravatar

Re: Pattern: must_build? return reason.

On Sun, Jul 5, 2009 at 4:10 PM, Peter Jaros<peter.a.jaros <at> gmail.com> wrote:
>
>
> On Sun, Jul 5, 2009 at 5:50 PM, John Carter<john.carter <at> tait.co.nz> wrote:
>
>> # Returns a string with the reason I must do "blah", else nil.
>> def must_rebuild?
>> end
>>
>> reason = generated_file.must_rebuild?
>
> A neat thought, but frankly, this rubs me the wrong way. I would
> never expect a method called #must_rebuild? to return anything but a
> boolean.
>

It's very normal in dynamic languages to do this since any variable
can be evaluated in a "boolean context". In fact, Perl, from which
Ruby derives, does not have a boolean type preferring to do this sort
of thing instead.

Think of it as being analogous to exit codes in *nix. An exit code of
0 is a normal exit and everything is okay. Any other exit code means
something bad happened. Sometimes the code itself is meaningful and
sometimes further information can be obtained (e.g. in a log or in a
system variable.) So there are two pieces of information: did it work?
and if not, why not? The answers to these are combined to some degree.

> Why not offer a second method returning the reason?
>
(Continue reading)

John Carter | 6 Jul 2009 01:55
Picon

YAGDI You Are Gonna Debug It (was must_build? return reason.

On Sun, 5 Jul 2009, Peter Jaros wrote:

> On Sun, Jul 5, 2009 at 5:50 PM, John Carter<john.carter <at> tait.co.nz> wrote:
>
>> # Returns a string with the reason I must do "blah", else nil.
>> def must_rebuild?
>> end
>>
>> reason = generated_file.must_rebuild?
>
> A neat thought, but frankly, this rubs me the wrong way.  I would
> never expect a method called #must_rebuild? to return anything but a
> boolean.

In a language with nil, nil is false.

> Why not offer a second method returning the reason?
Requires a static variable to store the reason, and that it be invoked
before any other op overwrites that variable, or it must be
recomputed.

In general the principle is ``expose the reasons things occur, not just
"it did" or "it didn't"''. ie. Wherever you have a boolean, ask yourself
can you give more info out, either in channel like the above, or in a
side channel.

Whilst I approve of the YAGNI (You Ain't Gonna Need It) principle in
general, after all, most things you can create you aren't going to need.

But let's face YAGDI up front, You Are Gonna Debug It. So make it easy.
(Continue reading)

George Dinwiddie | 6 Jul 2009 02:18
Favicon

Re: Pattern: must_build? return reason.

Peter Jaros wrote:
> On Sun, Jul 5, 2009 at 5:50 PM, John Carter<john.carter <at> tait.co.nz> wrote:
> 
>> # Returns a string with the reason I must do "blah", else nil.
>> def must_rebuild?
>> end
>>
>> reason = generated_file.must_rebuild?
> 
> A neat thought, but frankly, this rubs me the wrong way.  I would
> never expect a method called #must_rebuild? to return anything but a
> boolean.

As Adam and John suggest, this sort of thing is part of the idiom of 
some dynamic languages (and C).  I suspect you're using a language where 
it's not part of the idiom.

In Java, I would choose a different return value, perhaps a Decision 
which would consist of a boolean and a String reason.  I go to custom 
classes relatively easily, as they often make the code easier to 
understand and to extend (to multiple reasons, for example).

  - George

--

-- 
  ----------------------------------------------------------------------
   * George Dinwiddie *                      http://blog.gdinwiddie.com
   Software Development                    http://www.idiacomputing.com
   Consultant and Coach                    http://www.agilemaryland.org
  ----------------------------------------------------------------------
(Continue reading)

Peter Jaros | 6 Jul 2009 03:02
Picon
Gravatar

Re: YAGDI You Are Gonna Debug It (was must_build? return reason.

On Sun, Jul 5, 2009 at 7:55 PM, John Carter<john.carter <at> tait.co.nz> wrote:
>
> On Sun, 5 Jul 2009, Peter Jaros wrote:
>
>> On Sun, Jul 5, 2009 at 5:50 PM, John Carter<john.carter <at> tait.co.nz> wrote:
>>
>>> # Returns a string with the reason I must do "blah", else nil.
>>> def must_rebuild?
>>> end
>>>
>>> reason = generated_file.must_rebuild?
>>
>> A neat thought, but frankly, this rubs me the wrong way. I would
>> never expect a method called #must_rebuild? to return anything but a
>> boolean.
>
> In a language with nil, nil is false.
>

Ok.  And if you only treat it as a boolean, that's fine.  What rubs me
the wrong way is making it part of the *defined behavior* to return
something that's not a boolean.  The line

    reason = generated_file.must_rebuild?

looks really confusing to me.  If I came across that line while trying
to navigate a codebase, I'd do a doubletake.  Like I said, it's a neat
idea, but on the whole it seems more harmful than helpful.

>> Why not offer a second method returning the reason?
(Continue reading)

Peter Jaros | 6 Jul 2009 03:08
Picon
Gravatar

Re: Pattern: must_build? return reason.

On Sun, Jul 5, 2009 at 8:18 PM, George Dinwiddie<lists <at> idiacomputing.com> wrote:
>
> Peter Jaros wrote:
>> On Sun, Jul 5, 2009 at 5:50 PM, John Carter<john.carter <at> tait.co.nz> wrote:
>>
>>> # Returns a string with the reason I must do "blah", else nil.
>>> def must_rebuild?
>>> end
>>>
>>> reason = generated_file.must_rebuild?
>>
>> A neat thought, but frankly, this rubs me the wrong way. I would
>> never expect a method called #must_rebuild? to return anything but a
>> boolean.
>
> As Adam and John suggest, this sort of thing is part of the idiom of
> some dynamic languages (and C). I suspect you're using a language where
> it's not part of the idiom.

Is it really?  I've seen similar things in C all the time, and I've
always found it terribly un-expressive.  I've never seen anything like
this in Ruby.  Predicate methods are, as a rule, treated as booleans.

The fact that the value *can* be used as a boolean doesn't make it
right (unless you only use it as a boolean anyhow, in which case the
behavior's pointless).  Return whatever you want from the method.
*Using* the value of a predicate method as anything other than a
boolean, though, is weird and hard to read.

Peter
(Continue reading)

Ron Jeffries | 6 Jul 2009 03:12
Favicon

Re: Pattern: must_build? return reason.

Hello, Peter.  On Sunday, July 5, 2009, at 7:10:30 PM, you wrote:

>> reason = generated_file.must_rebuild?

> A neat thought, but frankly, this rubs me the wrong way.  I would
> never expect a method called #must_rebuild? to return anything but a
> boolean.

Suppose you didn't want two methods, that you wanted it to work this
way. What would you call the method?

Ron Jeffries
www.XProgramming.com
www.xprogramming.com/blog
Any errors you find in this are the work of Secret Villains,
whose mad schemes will soon be revealed. -- Wil McCarthy

------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/refactoring/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/refactoring/join
    (Yahoo! ID required)
(Continue reading)


Gmane