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
- use a decorator/presenter (i think this is overkill)
set the value of the placeholder in the controller
@response.followup = 'Would you like to add a note?' if response.blank?
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
Shading Mask Algorithm for Radiation Calculations
Get List Timeline by Using Twitter Gem
Why Do Numeric String Comparisons Give Unexpected Results
How to Get Multiple-Line User Input in Ruby
Hardcoded "Require 'Debug'" Can't Find the Sourcefile
Which Plugins/Gems Should I Use to Dynamically Generate Thumbnails On-The-Fly in Rails 3
Sublime Text Can't Understand Gets.Chomp
Can't Dup Nilclass on Association Methods
How to Use String Methods on Utf-8 Characters
Ruby: Why Are All Coordinates Getting Updated in an Array of Arrays
Ruby 1.8: Hash#Sort Not Return Hash But Array (Better Way to Do This)
Idiomatically Mock Openuri.Open_Uri with Minitest
Testing HTML5 File Upload with Capybara/Selenium Webdriver - Ruby