hoodwink.d enhanced
RSS
2.0
XHTML
1.0

RedHanded

Object#blank? #

by why in inspect

So, I’d like to submit Object#blank? as an RCR. I use this code in nearly all of my web application projects.

 class Object
   def blank?
     if respond_to? :empty?
       empty?
     elsif respond_to? :zero?
       zero?
     else
       !self
     end
   end
 end

This has been begging for addition into Ruby for years. A bit of background:

  • 2000: Jim Menard suggests nil.empty?.
  • 2002: Dave Thomas starts to further work up nil.empty?. Opposition brews. (Note that the possibility of nil becoming an Enumerable is kicked around!)
  • 2004: Zero is true … whoda thunk? thread delves in and out of the character of nil, 0, "" and so on. However, the discussion really revolves around whether zero could be treated as false in a future Ruby incarnation.
  • 2005: Just last month, Dan Fitzpatrick revisited the same nil.empty? pitch we’ve seen in years past.

In all, the two major points of backlash have been:

  1. Naming the thing. Some feel that empty? implies a container. A container which isn’t there for nil and 0. Another suggestion was vapid? but, uh, no.
  2. That there is no case in which 0 should be grouped with nil and "". I suppose many people are more commonly looking for "0" to belong to this group as well. Which means you have to use .to_i.zero?. Very similar to .to_s.empty?.

I’m thinking Object#blank? is a good solution. The name doesn’t imply a container. It implies valuelessness, which is what we are testing for.

This reduces the common case of:

 if venue['neighborhood'].to_s.empty?

To:

 if venue['neighborhood'].blank?

I’ve grouped 0 in there as well. It’s useful for YAML. Since YAML loads types naturally, you rarely run into a string like "0". And since I’m calling zero?, it works for floats as well.

Given this YAML invoice:

 sku:   BSK115
 price: 15.60
 tax:   0.00
 total: 15.60

I can easily check the tax, covering the case in which the tax is completely left out.

 print "Tax-free" if invoice['tax'].blank?

So, what do you think? Worthwhile RCR? Am I off on the name? Has our time come for this at last?

I’ve just submitted this proposal as RCR 295, which also weighs the possibility of a to_b conversion. This may kill the RCR, but I’d like to vote and ultimately find the best solution. I still prefer Object#blank?. But either is a move ahead.

said on 04 Mar 2005 at 12:17

blank? is the best name I’ve heard for this thus far. I still have mixed feelings about 0 being considered “blank”—although that is an issue with the name, not with the functionality.

This precise functionality is very, very needed.

said on 04 Mar 2005 at 12:39

I also like blank?.

said on 04 Mar 2005 at 15:13

I like the concept, but I’m iffy about the name. What about null? nothing? void? ziltch? vacuous?

Or, along the lines of ring thoery: annihilator? :)

Ok, just kidding, blank? is actually pretty good.

said on 04 Mar 2005 at 15:20

I think nada? covers all the bases, even 0.

said on 04 Mar 2005 at 20:33

How about

nix?

Actually, the one that makes the most sense to me is

none?

said on 04 Mar 2005 at 20:35

How about a Zen mu? for detecting when there’s no answer?

said on 04 Mar 2005 at 21:21

You monkeys. Give me back my chapstick.

said on 04 Mar 2005 at 23:40

Only zeroes are monkeyproof. monkeyproof?

said on 05 Mar 2005 at 00:54

There has been an initiative of to_b. I pretty much liked that because its succint, mixes nicely with the existing to_* method army and deadly precise: what you want from the damned object is nothing else, just to spit out a Boolean value. No more hype please, come out and speak up which side you take! Pretty apocalyptic, eh?

said on 05 Mar 2005 at 06:33

But doesn’t isn’t 0.to_b dangerously close to the !0 debate? I think blank?’s main benefit is the fact that it sounds fuzzier. Does that make any sense?

said on 05 Mar 2005 at 08:53

What’s wrong with .blank? ? Love it.

said on 05 Mar 2005 at 13:20

I am blank.

said on 05 Mar 2005 at 13:20

So am I!

said on 05 Mar 2005 at 13:20

Me too!

said on 05 Mar 2005 at 13:21

I’m completely blank.

said on 05 Mar 2005 at 13:25

I’m with Bruce. I don’t really want to see methods that switch the polarity of 0 or "".

I just want every class to have a test for their most nominal value.

said on 05 Mar 2005 at 13:31

I’m not blank, honest! (heh heh heh)

said on 05 Mar 2005 at 13:33

False, I know you’re lying, as usual. The rest of you kids, pipe down and listen to Mister Why.

So let’s see, who do we have?

0
0.0
"" 
[]
{}
false
</p>

Am I forgetting anybody?  Hands up if I forgot to count you.

Oh yeah, "nil".  Well, I suppose it's no surprise you didn't pipe up.

Did I leave anybody else out?
said on 05 Mar 2005 at 13:47

Hmm, that SetOfBlankThings shoudl really hit the Preview button before posting. ahem

Anyhow. I like it. I think there’s a need for, as _why calls it, the “most nominal value”. I know it’s context-dependent. Sometimes zero is meaningful. Sometimes an empty string is a response. There are just enough cases where 0, nil, and an empty string are all “no response” or “not applicable”. It would be nice to have a test that everything responds to that catches this case.

As for to_b, I’ve never understood why that doesn’t exist. It would be different if the language didn’t depend on boolean values, but it does.

if [########]
  puts "It's true" 
else
  puts "It's false" 
end

Obviously, the language already has a “to_b” conversion it’s doing. Whatever is in that blanked-out area is evaluating to either true or false.

If false and nil returned false for to_b and everything else returned true, that would match what the language is doing internally.

I don’t see the downside to adding a to_b method to Object… on the other hand, at the moment I can’t remember when I needed it either. It juse seems to be missing.

said on 05 Mar 2005 at 15:04

http://dev.rubyonrails.org/ticket/783

said on 05 Mar 2005 at 15:44

What about Files, Dirs, and Ranges?

Blank for size 0
and
Blank for seek(0,IO::SEEK_END); pos 0

said on 05 Mar 2005 at 19:25

Sorry to rain on the parade, but I don’t like 0.blank? == true

As a CS guy, it just feels wrong to me to call 0 “blank”. I prefer the to_b approach: just like to_s asks for a string representation, to_b asks the object to represent itself as either true or false. Whether Fixnum chooses to return false for the valuation 0 is then a matter of convention, and not one of linguistics like with some of the other choices.

said on 05 Mar 2005 at 20:25

Gosh, maybe if we’d had a Boolean class we could have subclassed it years ago to solve our needs. But NOOOOOOOO , someone insists on being stubborn.

said on 05 Mar 2005 at 21:09

Well, it sounds like there’s two ideas here. One group wants to cast these values as false—which is reasonable, citing 0.to_a and other fuzzy conversions. The other clan wants a fuzzy conditional—reasonable considering the back history of question methods in Ruby.

It may be worthwhile to have both, but we clearly need at least one. This is a common snag.

I guess it boils down to: when a n00b on ruby-talk says, “Why does 0 evaluate to true in an if-statement?”—which of these alternatives are you most happy with presenting?

said on 05 Mar 2005 at 21:25

You’re thinking too locally, why. Imagine if we have a Boolean class. That class has two methods: true and false (which would be declared as global methods to keep the familiar syntax). Conditionals would then be based on how those methods are defined.

So, current behavior:
if venue['neighborhood'].to_s.empty?
Your proposed behavior:
if venue['neighborhood'].blank?
My proposed behavior:
class Boolean
   def false
      nil or "" or 0
   end
end

# false if empty or 0
if venue['neighborhood'] 
Then, instead of having to call .empty? on every individual object, you set it once, globally.
said on 06 Mar 2005 at 00:22

The value of 0.blank? is totally dependent upon the application logic, just like your YAML invoice example shows. I don’t like this being in the Ruby language at all.

said on 06 Mar 2005 at 11:49

I’d like to see Ruby add true? and false? methods rather than a to_b method.

said on 06 Mar 2005 at 12:14

what about zero?

string.zero? (is it zero in length)

num.zero? (does it equal zero)

obj.zero? (does it reference address zero … do we have such an address in the heap…)

list.zero? (how many elements are there, zero? )

DO not consider it, it is just a joke!

said on 06 Mar 2005 at 15:13

BergerProposal++

People shouldn’t lambast the convention of 0 = false. It’s more than just a c compatability. Do a google for “Iverson Convention.” It’s common usage in math, and is particularly convenient in expressing summations dependant on some predicate:

x = Sigma_i[P(i)*F(i)]

The only contexts I can think of where zero should return true are probibly better expressed by explicit referenc to an exists? or defined? method.

said on 06 Mar 2005 at 19:21

Jason: Leaving aside my own views on it, I think it’s highly unlikely that “zero as true” is going to change. Too many people, not the least of whom is the language designer, like it that way. So it’s probably better to focus on something that has a chance of changing.

I particularly liked one of the messages in the “whoda thunk?” thread: ruby-talk:100810. The poster considers “zero as true” to be a “Licorice Test” for Ruby; either you love it or you hate it. I think this particular flavor is rather fundamental to Ruby being Ruby, it’s right up there with “Everything’s an object”

You could say: “All answers are true except the non-answer (nil), and true and false are their representatives.”

said on 07 Mar 2005 at 00:55

This proposal is now RCR 295. Let’s get a formal vote. Thanks for all your input. This has been totally productive.

Comments are closed for this entry.