Empty value

Hi,

Is there a better way to test if a variable|instance is empty ?
I usually use :

@name = 'Guest' if @name.empty?

There's no way to have a trick like the following ?
@name ||= 'Guest' # except here @name need to be 'nil' or 'false' not empty

Thank you very much for you replies.

/Nathan

Is there a better way to test if a variable|instance is empty ?
I usually use :

@name = 'Guest' if @name.empty?

I generally use something like

    @name = (@name.nil? || @name.empty?) ? 'Guest' : @name

Is that objectively better? Not really.

I confess that in one (Sinatra) application here I have monkey-patched to give something similar to Rails' presence(), so I can just say

    @name = 'Guest' if @name.blank?

...because nil.blank? -> true (also " ".blank?, [nil].blank?, ... but I digress.)

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

Depends on your assumptions on what value this variable can hold. If it is
always a String, then
@name = 'Guest' if @name.empty?

If it can be a nil or a String, then
@name = 'Guest' if @name.nil? || @name.empty?

With rails/activesupport it can be shortened to
@name = @name.presence || 'Guest'
http://api.rubyonrails.org/classes/Object.html#method-i-presence

@name ||= 'Guest' is not what you want if @name can hold a non-nil value
http://ruby-doc.org/core-2.3.3/doc/syntax/assignment_rdoc.html#label-Abbreviated+Assignment

···

On Thu, Nov 24, 2016 at 12:24:15PM +0400, Nathan Guilty wrote:

Hi,

Is there a better way to test if a variable|instance is empty ?
I usually use :

@name = 'Guest' if @name.empty?

There's no way to have a trick like the following ?
@name ||= 'Guest' # except here @name need to be 'nil' or 'false' not empty

Thank you very much for you replies.

/Nathan

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

I think that highlights that using #empty? to detect "unset" is just
the wrong approach. Any variable is nil - unless assigned otherwise.
So it's much more easier to rely on nil as the unassigned state.
Compare

class C1
  def initialize
    @name = ""
  end

  def name
    @name = generate_name() if @name.empty?
    @name
  end
end

class C2
  def name
    @name ||= generate_name()
  end
end

For some arbitrary implementation of #generate_name.

If the empty string is some form of input then I think it should be
checked there right away, e.g.

def name=(s)
  @name = s if s && !s.empty?
end

or

def name=(s)
  @name = normalize(s)
end

def normalize(s)
  s.gsub(/\A\s+|\s+\z/, '').tap |x|
    raise "Wrong s" unless x.empty?
  end
end

But I'm digressing...

Kind regards

robert

···

On Thu, Nov 24, 2016 at 9:56 AM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

Is there a better way to test if a variable|instance is empty ?
I usually use :

@name = 'Guest' if @name.empty?

I generally use something like

    @name = (@name.nil? || @name.empty?) ? 'Guest' : @name

Is that objectively better? Not really.

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

I think that highlights that using #empty? to detect "unset" is just
the wrong approach. Any variable is nil - unless assigned otherwise.
So it's much more easier to rely on nil as the unassigned state.

Well, sure. But if you are capturing the state from somewhere else then you don't get to make that assumption. For example, if you are entering it on the command line with `gets()` (the simplest example), if the user presses return you will get an empty string, not nil.

I can certainly say

    entered_value = nil if entered_value.empty?

... and then pass it to your very elegant class -- but this is back to the same problem we had before, except that the code is now in two different places.

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

I think that highlights that using #empty? to detect "unset" is just
the wrong approach. Any variable is nil - unless assigned otherwise.
So it's much more easier to rely on nil as the unassigned state.

Well, sure. But if you are capturing the state from somewhere else then you don't get to make that assumption. For example, if you are entering it on the command line with `gets()` (the simplest example), if the user presses return you will get an empty string, not nil.

But you surely would not process user input without validation, would you?

I can certainly say

    entered_value = nil if entered_value.empty?

... and then pass it to your very elegant class -- but this is back to the same problem we had before, except that the code is now in two different places.

But that makes a difference. If the value is passed on via some public
method and there are illegal string values that method should ideally
do validation. The whole point of OO is that you restrict the set of
states an instance can be in (class invariant). OTOH it makes sense to
immediately validate user input to give better UX (e.g. by presenting
an error message and repeating the input).

Now, whether that should be done for every script is a different
question. I know too little about the use case of OP so lots of
speculations here. I am trying to throw up alternatives which might or
might not be better suited to the OPs situation.

The real motivation for my earlier response was to avoid situations
where people initialize with an empty string. I have seen examples of
this on this list and most of the time that was done because people
thought they need to give all member variables explicitly a value
during construction.

Kind regards

robert

···

On Thu, Nov 24, 2016 at 1:13 PM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/