empty? vs. blank? vs. length > 0

Hello,

Which is the best method to use, I am at a quandary over the most basic of tests!

I want something like

<%= @object.description unless @object.description.empty? -%>

So the `unless` could be any of these:

  unless @object.description.empty?   unless @object.blank?   if @object.length > 0

The last one is the most consistent to my observations, but what are your ideas on the best method?

Usually, with active model fields, you want blank? This handles the
two cases where the result is nil and where the result is the empty
string. Off the top of my head, and I could be wrong about this, but
calling length on a null throws an exception. However, calling
blank? on a null is not a problem.

Paul

Mindtonic wrote:

  unless @object.blank?

I find blank? to be the best in Rails. It is defined on all objects and has the meaning you most often mean. empty? is a little more common outside of Rails since blank? is a Rails extension to ruby but empty? doesn't handle cases like nil or a string with all space characters. length > 0 is basically equivalent Ruby's definition of empty? just more verbose and less obvious.

I would stay stick to blank? if you are in Rails.

Eric

Could you do <% if @object.description %> <%= @object.description %>

??

jg wrote:

Could you do <% if @object.description %> <%= @object.description %>

??

You could. It could be more consisely written as:

<%=object.description if @object.description%>

The problem is in Rails only "false" and nil are evaluated as false. So this doesn't cover cases where the value is an empty string or even a string with just spaces. Blank does cover those cases. So it is better to write:

<%=@object.description unless @object.description.blank?%>

If course in this case if object.description is blank then nothing will really be printed anyway so you might as well just simpify this to:

<%=@object.description%>

But if you have more complex logic you might want to use the condition. For example:

<%=link_to @object.owner, owner_path(@object.owner) unless @object.owner_id.blank?%>

Eric

This would work, unless @object was nil, then boom :slight_smile: as nill would not have a method “description”.

jg wrote:

blank? is negative. I like positive booleans:

module Relevate   def relevant?     return ! blank?   end

  def relevance     return to_s if relevant?   end end

# ERGO dry these up class String     def blank?         return strip.size == 0     end end

class NilClass     def blank?; true; end end

NilClass.send :include, Relevate String .send :include, Relevate

Use .relevant? as the negation of .blank?

Use .relevance to avoid this:

  x = y.relevant? ? y.to_s : default

You can just say:

   x = y.relevance || default

Hi --

blank? is negative.

I disagree; I think it's a positive measure. It just happens to be a positive measure of emptiness. I put it in the same category as nil?, zero?, and empty?, all of which are positive tests for emptiness (or whatever the best master term is).

I like positive booleans:

module Relevate def relevant?    return ! blank? end

def relevance    return to_s if relevant? end end

I'm not sold on the concept of an object's "relevance" being coupled to a string representation. At least for me, "relevance" doesn't denote or connote anything along those lines.

# ERGO dry these up class String    def blank?        return strip.size == 0    end end

class NilClass    def blank?; true; end end

The original versions are essentially the same as those already, though the original String#blank? does lazy creation of the stripped version of the string:

   class NilClass #:nodoc:      def blank?        true      end    end

   class String #:nodoc:      def blank?        empty? || strip.empty?      end    end

So the repetition of empty? isn't gratuitous.

NilClass.send :include, Relevate String .send :include, Relevate

Use .relevant? as the negation of .blank?

What if an empty string is relevant, in the sense of being of interest to the programming logic?

   <% if name.blank? %>     <p>You don't have a name!</p>    <% end %>

I'd find it very hard to interpret this:

   <% unless name.relevant? %>     <p>You don't have a name!</p>    <% end %>

Use .relevance to avoid this:

x = y.relevant? ? y.to_s : default

You can just say:

  x = y.relevance || default

Again, I would never pick up on the fact that the "relevance" of y means a string representation. Maybe "populated?" would be better.

David

dblack wrote:

> blank? is negative.

I disagree;

See below.

> class String > def blank? > return strip.size == 0 > end > end

The original versions are essentially the same as those already,

Noted; I shouldn't even have copied them in. They came from source that might not yet have ActiveSupport available.

What if an empty string is relevant, in the sense of being of interest to the programming logic?

then you use blank? .

I'd find it very hard to interpret this:

   <% unless name.relevant? %>

That's because unless is also negative, so you lack no double negatives.

And sometimes unless is the clearer expression.

Again, I would never pick up on the fact that the "relevance" of y means a string representation. Maybe "populated?" would be better.

I could use a better name, but "populated" is technical, and "relevant" is supposed to mean something is semantically valuable.

Hi --

I'd find it very hard to interpret this:

   <% unless name.relevant? %>

That's because unless is also negative, so you lack no double negatives.

And sometimes unless is the clearer expression.

Definitely; I meant specifically that "unless name.relevant?" was tough going. But if you hang onto blank? (which I had thought you weren't but I now understand you are), you wouldn't have to use it. In general I'm a big fan of unless in place of "if !", although I do find this hard to take in sometimes:

   unless x > y      ...    else      ...    end

I end up sort of translating it back to if in my head.

Again, I would never pick up on the fact that the "relevance" of y means a string representation. Maybe "populated?" would be better.

I could use a better name, but "populated" is technical, and "relevant" is supposed to mean something is semantically valuable.

The problem is that semantic value doesn't always map to non-emptiness of strings or arrays, or non-nilness of objects. I suppose "full" would be one option, though it implies "full to capacity". Of course, all of these container-sounding names are ultimately wrong for nil, but it's convenient to include nil since a lot of the need for the methods is to handle empty containers and nil in the same conditional branch.

David