On Dec 27, 9:19 am, Pratik <[email protected]> wrote:
> I see. But it does feel like code smell to me. And, you can always do
> something like :
>
> region = [params[:state], params[:country], 'US'].detect(&:present?)

On Dec 27, 10:43 am, Duncan Beevers <[email protected]> wrote:
> Including all the items in an Array and picking the first present one
> circumvents any opportunity to use logic short-circuiting to avoid
> unnecessary, potentially expensive calculation, not to mention unnecessary
> allocation of container objects and the overhead of symbol-to-proc.

Yes, that's too much overhead,  Here's the benchmark:

>> state=nil; country='Canada';
>>  Benchmark.bm(10) do |bm|
>>   bm.report("nonblank?") { n.times { region = state.nonblank? || 
>> country.nonblank? || 'US' } }
>>   bm.report("detect   ") { n.times { region = [state.nonblank?, country, 
>> 'US'].select &:present? } }
>> end
                user     system      total        real
nonblank?   0.210000   0.000000   0.210000 (  0.212206)
detect      2.320000   0.070000   2.390000 (  2.487010)

Over 10X slower!  The above example doesn't emphasize short-circuiting
either.  You could easily find examples that were 100X slower because
of complex expressions.

I definitely wouldn't write it that way.  If I had to live without
nonblank?, this is what I'd write:

  region = (params[:state]     unless params[:state].blank?) ||
               (params[:country] unless params[:country].blank?) ||
               'US'
but you can see that's not DRY since every argument is mentioned
twice.  That's what led us to add nonblank?.  It's concise, DRY, and
performs well.

On Dec 27, 11:51 am, Yehuda Katz <[email protected]> wrote:
> My biggest concern with nonblank? is that idiomatic Ruby is to return a
> boolean from question mark methods.

Generally that's true, but Ruby has nonzero? which behaves exactly
like nonblank?: you get a value back that is _equivalent_ to boolean
but has other uses too.  Another Ruby example is =~ which returns nil
or an index, although that doesn't end in ?.

> I like Pratik's solution, and would like to see a scenario where the 
> short-circuit logic is important

I just grep'd our company's code base (65K LOC) and found 190 usages
of nonblank?, not including the definition and tests.  About 70% are
using it as a boolean (we haven't used present? since that was
introduced in Rails 2.2 and we were on 2.1 until the end of the
summer) but 30% are the pattern discussed here.  For example, from our
EmailAddress class:

  @friendly_name = tmail.name.nonblank? || friendly_name

I also found several cases where the mapping to nil was explicitly
important (because we wanted it to the be the same as "not present")
as in

  vid = cookies[:vid].nonblank?

Of the 70% that treat nonblank?'s result as a boolean, I didn't find a
single case that put !! in front to force the result to a proper
boolean. Likely that's because when you really want a true boolean, !
blank? reads best.

-Colin

--

You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-core?hl=en.


Reply via email to