Rails Object#Blank? VS. String#Empty? Confusion

Rails Object#blank? vs. String#empty? confusion

Rails is kinda tricky in how it documents its blank? method. Even though Object#blank? claims to also detect whitespace strings, it is implemented with String#blank? to handle the whitespace case and Object#blank? to catch the generic case. (blank? is defined on a few other classes, too, to save time.)

activesupport/lib/active_support/core_ext/object/blank.rb, line 66:

class String
def blank?
self !~ /\S/
end
end

rails Object.blank? and whitespace

It's overridden for Strings:

From activesupport/core_ext/blank.rb

class String #:nodoc:
def blank?
self !~ /\S/
end
end

String is .blank? but neither empty nor whitespace

the three spaces: [32,160,32]

ASCII 160 is a non breaking space usually found in HTML, and apparently not recognized as squish as a space. Try to replace it before:

string.gsub(160.chr, ' ').squish

Is there a Ruby string#blank? method?

AFAIK there isn't anything like this in plain Ruby. You can create your own like this:

class NilClass
def blank?
true
end
end

class String
def blank?
self.strip.empty?
end
end

This will work for nil.blank? and a_string.blank? you can extend this (like rails does) for true/false and general objects:

class FalseClass
def blank?
true
end
end

class TrueClass
def blank?
false
end
end

class Object
def blank?
respond_to?(:empty?) ? empty? : !self
end
end

References:

https://github.com/rails/rails/blob/2a371368c91789a4d689d6a84eb20b238c37678a/activesupport/lib/active_support/core_ext/object/blank.rb#L57
https://github.com/rails/rails/blob/2a371368c91789a4d689d6a84eb20b238c37678a/activesupport/lib/active_support/core_ext/object/blank.rb#L67
https://github.com/rails/rails/blob/2a371368c91789a4d689d6a84eb20b238c37678a/activesupport/lib/active_support/core_ext/object/blank.rb#L14
https://github.com/rails/rails/blob/2a371368c91789a4d689d6a84eb20b238c37678a/activesupport/lib/active_support/core_ext/object/blank.rb#L47

And here is the String.blank? implementation which should be more efficient than the previous one:

https://github.com/rails/rails/blob/2a371368c91789a4d689d6a84eb20b238c37678a/activesupport/lib/active_support/core_ext/object/blank.rb#L101

Return string if data is empty, nil or blank?

check if you have presence available in your rails version. If it is, you can do the following

<%= f.text_area :comment, placeholder: @response.followup.presence || "Would you like to add a note?" %>

If it's not available, you can choose one of the following

  1. use a decorator/presenter (i think this is overkill)
  2. set the value of the placeholder in the controller

    @response.followup = 'Would you like to add a note?' if response.blank?

  3. use a ternary operator in the view

    <%= f.text_area :comment, placeholder: (@response.followup.blank? ? "Would you like to add a note?" : @response.followup) %>

Duplicating .blank? in standard Ruby

You forget about this - https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb#L95

class String
# A string is blank if it's empty or contains whitespaces only:
#
# "".blank? # => true
# " ".blank? # => true
# " something here ".blank? # => false
#
def blank?
self !~ /\S/
end
end

ActiveRecord - check if value is null, 0 or 1

A case uses === for comparison so that's equivalent to:

if false === a
'false 0'
elsif true === a
'true 1'
elsif blank? === a
'blank or nil'
else
nil
end

Rails adds a blank? method to Object that looks like this:

def blank?
respond_to?(:empty?) ? empty? : !self
end

so you can call blank? anywhere, even without a specified receiver: there will always be a self and it will always be an Object. Now you should see that when blank?, while syntactically valid, makes no sense at all: it doesn't call a.blank? and see if a true value came back, it simply checks self.blank? === a for whatever self happens to be.

You're probably better off using an explicit if/else for this:

def result(a)
# false.blank? is true so you don't want a.blank? here.
if(a.nil?)
'nil'
elsif(a)
'true 1'
else
'false 0'
end
end

Rails 3.2 - How Rails blank? method works internally?

This project is open source, so just take a look at the source: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb

You'll see that there are individual methods written for the various classes (like String, Array, etc.)



Related Topics



Leave a reply



Submit