NEWBIE QUESTION: pattern with nil

(basi) #1

Hello,
I'm a bit tired typing:

if a == "" or a == nil
if a != "" and a !== nil

I'm sure there is a Ruby way to do this.

Thanks for the help.
basi

(David A. Black) #2

Hi --

···

On Wed, 10 Aug 2005, basi wrote:

Hello,
I'm a bit tired typing:

if a == "" or a == nil
if a != "" and a !== nil

I'm sure there is a Ruby way to do this.

You can normalize it to a string:

   if a.to_s.empty?

or, for the opposite:

   unless a.to_s.empty?

David

--
David A. Black
dblack@wobblini.net

(Ara.T.Howard) #3

i generally use

   harp:~ > cat a.rb
   a = 'foobar'
   p 42 unless a.nil? or a.empty?

   a = nil
   p 42 unless a.nil? or a.empty?

   harp:~ > ruby a.rb
   42

because the meaning is very clear. for shorter i use

   harp:~ > cat a.rb
   a = 'foobar'
   p 42 unless a.to_s.empty?

   a = nil
   p 42 unless a.to_s.empty?

   harp:~ > ruby a.rb
   42

cheers.

-a

···

On Wed, 10 Aug 2005, basi wrote:

Hello,
I'm a bit tired typing:

if a == "" or a == nil
if a != "" and a !== nil

I'm sure there is a Ruby way to do this.

Thanks for the help.
basi

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

(John Carter) #4

class NilClass
   def empty?
     true
   end
end

if a.empty?

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.

···

On Wed, 10 Aug 2005, basi wrote:

Hello,
I'm a bit tired typing:

if a == "" or a == nil
if a != "" and a !== nil

I'm sure there is a Ruby way to do this.

(Ara.T.Howard) #5

'normalize' is such a nicer word than 'cast' - i'll take it!

-a

···

On Wed, 10 Aug 2005, David A. Black wrote:

Hi --

On Wed, 10 Aug 2005, basi wrote:

Hello,
I'm a bit tired typing:

if a == "" or a == nil
if a != "" and a !== nil

I'm sure there is a Ruby way to do this.

You can normalize it to a string:

if a.to_s.empty?

or, for the opposite:

unless a.to_s.empty?

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
Your life dwells amoung the causes of death Like a lamp standing in a strong breeze. --Nagarjuna

===============================================================================

(BearItAll) #6

I vote for this one because a good programmer is a lazy sod. Where ever
you would end up doing a thing more than once, write it is such a way that
you never have to type it again.

···

On Wed, 10 Aug 2005 14:44:15 +0900, John Carter wrote:

On Wed, 10 Aug 2005, basi wrote:

Hello,
I'm a bit tired typing:

if a == "" or a == nil
if a != "" and a !== nil

I'm sure there is a Ruby way to do this.

class NilClass
   def empty?
     true
   end
end

if a.empty?

(basi) #7

David A. Black wrote:

Hi --

> Hello,
> I'm a bit tired typing:
>
> if a == "" or a == nil
> if a != "" and a !== nil
>
> I'm sure there is a Ruby way to do this.

You can normalize it to a string:

   if a.to_s.empty?

or, for the opposite:

   unless a.to_s.empty?

David

--
David A. Black
dblack@wobblini.net

Thanks all for the suggestions. This solution appeals to me because I
don't have to define anything new. I wonder if, in general, this is a
good criteria for evaluating solutions.

basi

···

On Wed, 10 Aug 2005, basi wrote:

(Austin Ziegler) #8

Just, please, don't do it in a library that you unleash on the rest of
the world. It changes the contract for +nil+, and I prefer that it
*not* respond to #empty?, because the concept isn't *quite* accurate.
One may as well define #zero? if you're going to to that (but +nil+
isn't zero, either, just as it isn't the empty string or array).
Better is to use the foo.nil? or foo.empty? construct and be explicit,
or foo.to_s.empty? if you want to silently cast ("normalize").
Changing nil to respond to #empty? is an implicit change that also
changes its meaning.

-austin

···

On 8/10/05, BearItAll <bearitall@rassler.co.uk> wrote:

On Wed, 10 Aug 2005 14:44:15 +0900, John Carter wrote:
> class NilClass
> def empty?
> true
> end
> end
> if a.empty?
I vote for this one because a good programmer is a lazy sod. Where ever
you would end up doing a thing more than once, write it is such a way that
you never have to type it again.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

(Aredridel) #9

Thanks all for the suggestions. This solution appeals to me because I
don't have to define anything new. I wonder if, in general, this is a
good criteria for evaluating solutions.

Certainly not the only criteria one should use -- but it sure feels
right. It's the same reason I'd use an array, not some ContainerOfFoo
class that I define -- if the builtins do the job, use them!

(James Edward Gray II) #10

My two cents:

Ruby makes it trivially easy to alter the behavior of the core classes. It's a powerful feature and I love it, but it's also easy to abuse.

If you're working on a Domain Specific Language and want to alter the core classes to fit that model, I say go for it. If you can add a few methods to Array or String or whatever to help with the task you are currently tackling, again I say do it.

However, I'm usually against hacks to change the behavior of the core classes. You could break a lot of code that way, possibly in Ruby's rich standard library. Plus, your teaching yourself to rely on non-core techniques, which I doubt will help in the long run. Put in terms of this thread, I'm fine with Rails' blank() method (just adding some functionality), but leery of adding empty?() to nil (that's not how Ruby's nil works).

Again though, that's all just my opinion. Obviously, Ruby allows people to add empty?() to nil and some do.

James Edward Gray II

···

On Aug 10, 2005, at 2:06 PM, basi wrote:

Thanks all for the suggestions. This solution appeals to me because I
don't have to define anything new. I wonder if, in general, this is a
good criteria for evaluating solutions.

(Wilson Bilkovich) #11

Rails defines a method called "blank?" on the class Object.
Here's what it looks like:

# "", " ", nil, and 0 are all blank
  def blank?
    if respond_to?(:empty?) && respond_to?(:strip)
      strip.empty?
    elsif respond_to? :empty?
      empty?
    elsif respond_to? :zero?
      zero?
    else
      !self
    end
  end

···

On 8/10/05, Austin Ziegler <halostatue@gmail.com> wrote:

On 8/10/05, BearItAll <bearitall@rassler.co.uk> wrote:
> On Wed, 10 Aug 2005 14:44:15 +0900, John Carter wrote:
> > class NilClass
> > def empty?
> > true
> > end
> > end
> > if a.empty?
> I vote for this one because a good programmer is a lazy sod. Where ever
> you would end up doing a thing more than once, write it is such a way that
> you never have to type it again.

Just, please, don't do it in a library that you unleash on the rest of
the world. It changes the contract for +nil+, and I prefer that it
*not* respond to #empty?, because the concept isn't *quite* accurate.
One may as well define #zero? if you're going to to that (but +nil+
isn't zero, either, just as it isn't the empty string or array).
Better is to use the foo.nil? or foo.empty? construct and be explicit,
or foo.to_s.empty? if you want to silently cast ("normalize").
Changing nil to respond to #empty? is an implicit change that also
changes its meaning.

(John Carter) #12

Well...

I did say long and loud and tediously in the RCR 303 discussion that we there are several meanings to nil and we need to change ruby to distinguish between them.

The original poster had a NoThing type of nil. Your fear arises from the possibility of applying the empty? method to an Unitialized or NotApplicable type of nil.

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.

···

On Wed, 10 Aug 2005, Austin Ziegler wrote:

On 8/10/05, BearItAll <bearitall@rassler.co.uk> wrote:

On Wed, 10 Aug 2005 14:44:15 +0900, John Carter wrote:

class NilClass
   def empty?
     true
   end
end
if a.empty?

I vote for this one because a good programmer is a lazy sod. Where ever
you would end up doing a thing more than once, write it is such a way that
you never have to type it again.

Just, please, don't do it in a library that you unleash on the rest of
the world. It changes the contract for +nil+, and I prefer that it
*not* respond to #empty?, because the concept isn't *quite* accurate.

(Gavin Kistner) #13

Thanks all for the suggestions. This solution appeals to me because I
don't have to define anything new. I wonder if, in general, this is a
good criteria for evaluating solutions.

[snip]

However, I'm usually against hacks to change the behavior of the core classes. You could break a lot of code that way, possibly in Ruby's rich standard library. Plus, your teaching yourself to rely on non-core techniques, which I doubt will help in the long run.

[snip]

This has been the biggest 'gotcha' for me; I started out with Ruby and slowly grew my own library of really convenient (to me) additions/changes to the core libraries. Invariably, I get to a point in my code where I want to release it, and I'm left with three choices:

a) Require people to include my library-of-hacks (in whole, since I don't have it broken into tiny pieces) if they want to use my sweet new library I'm releasing. Not a nice dependency.

b) Copy/paste the salient hacks into my library file so they go along together. Ugh, now I have a version control problem.

c) Rewrite my library not to use my own hacks, but instead strive to use only built-in stuff.

Usually, I choose (c).

If you're doing programs just for yourself, I personally suggest you do whatever makes your life easier. But the addiction to customizing the language can be problematic if you want to share your code.

···

On Aug 10, 2005, at 1:17 PM, James Edward Gray II wrote:

On Aug 10, 2005, at 2:06 PM, basi wrote:

(Adam Sanderson) #14

Don't worry, you can redefine it to return :mu
  http://en.wikipedia.org/wiki/Mu_(Japanese_word)
Or for added entertainment just return nil again.

Oh wait, you didn't want to confuse the rest of the world?
  .adam sanderson

(David A. Black) #15

Hi --

···

On Thu, 11 Aug 2005, John Carter wrote:

On Wed, 10 Aug 2005, Austin Ziegler wrote:

On 8/10/05, BearItAll <bearitall@rassler.co.uk> wrote:

On Wed, 10 Aug 2005 14:44:15 +0900, John Carter wrote:

class NilClass
   def empty?
     true
   end
end
if a.empty?

I vote for this one because a good programmer is a lazy sod. Where ever
you would end up doing a thing more than once, write it is such a way that
you never have to type it again.

Just, please, don't do it in a library that you unleash on the rest of
the world. It changes the contract for +nil+, and I prefer that it
*not* respond to #empty?, because the concept isn't *quite* accurate.

Well...

I did say long and loud and tediously in the RCR 303 discussion that we there are several meanings to nil and we need to change ruby to distinguish between them.

The original poster had a NoThing type of nil. Your fear arises from the possibility of applying the empty? method to an Unitialized or NotApplicable type of nil.

I would say that asking whether nil is empty is like asking whether 12
is empty: it just doesn't mean anything. Even having it say "false"
suggests that "true" is possible. In general, I don't think
non-container objects should be declaring themselves "empty".

David

--
David A. Black
dblack@wobblini.net

(John Carter) #16

My whole reply was a little tease....

My Hidden Agenda was...

* Looky See, very very nice NullObject pattern solution to this problem.

* Wait for the chorus of Yums! As people see how simple and tasty it is.

* Wait for the echo of Yucks as curmudgeons like you correctly note the
   downside.

* Pop up and say, "I told you so, we need to disambiguate the meanings of
   nil!"

Unfortunately the poor newbie gets sorrowfully confused in the process.

Sorry mate.

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.

···

On Thu, 11 Aug 2005, Gavin Kistner wrote:

c) Rewrite my library not to use my own hacks, but instead strive to use only built-in stuff.

(Austin Ziegler) #17

class NilClass
  def empty?
    true
  end
end
if a.empty?

I vote for this one because a good programmer is a lazy sod.
Where ever you would end up doing a thing more than once, write
it is such a way that you never have to type it again.

Just, please, don't do it in a library that you unleash on the
rest of the world. It changes the contract for +nil+, and I
prefer that it *not* respond to #empty?, because the concept
isn't *quite* accurate.

I did say long and loud and tediously in the RCR 303 discussion
that we there are several meanings to nil and we need to change
ruby to distinguish between them.

I didn't go into detail there, John, but it's worth noting that
originally Codd thought that there should be several different NULL
values for relational databases. Later in life, he came to believe
that NULL values (both the single NULL value in SQL databases and
the multiple NULL values in his original relational papers) were
bad.

The original poster had a NoThing type of nil. Your fear arises
from the possibility of applying the empty? method to an
Unitialized or NotApplicable type of nil.

Your proposal of multiple types of nil makes life harder. Instead
of:

  if foo.nil?
    # blah
  end

I would have to do:

  if foo.nothing? or foo.undefined? or foo.not_applicable?
    # blah
  end

The problem, as others have stated, is that adding #empty? to
NilClass implies a containment. I'd have as big a problem if we
added #empty? to Fixnum so that 0 returned true and everything else
returned false. (Indeed, would that be correct? Would -3.empty? be
true or false?)

Better to do:

  if foo.nil? or foo.empty?
    # blah
  end

The code is explicit and meaningful at that point. Multiple types of
NULL/nil values tend to confuse things far more than they help
things.

-austin

···

On 8/10/05, John Carter <john.carter@tait.co.nz> wrote:

On Wed, 10 Aug 2005, Austin Ziegler wrote:

On 8/10/05, BearItAll <bearitall@rassler.co.uk> wrote:

On Wed, 10 Aug 2005 14:44:15 +0900, John Carter wrote:

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

(John Carter) #18

class Fixnum
   def each
     # I'm throwing this exception, not because it is required,
     # but because a headache is damping my imagination
     # as to what -1.each means. I think it means the something
     # like collect or sum, but my head hurts too much to say.
     raise "Negative number" if self < 0

     (1..self).each{|i| yield 1}
   end

   def empty?
     self == 0
   end
end

12.each {|i| puts i}

1

What does NoThing contain?

Obvious it contains NoThing.

noThing.shift returns noThing.

Is NoThing empty?

Yes.

It's all like non-euclidean geometry. Nobody could prove Euclid's 5 postulate even though it was ugly enough to be a theorem not an axiom.

So some bright spark resolve to propose an alternative, intuitively wrong alternative to postulate 5 and then find the contradiction.

There wasn't one.

ie. Equally valid non-euclidean geometries exist.

The current axioms of "nil" are valid and consistent.

But more useful, equally consistent axioms of "nil" can be proposed.

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.

···

On Thu, 11 Aug 2005, David A. Black wrote:

The original poster had a NoThing type of nil. Your fear arises from the possibility of applying the empty? method to an Unitialized or NotApplicable type of nil.

I would say that asking whether nil is empty is like asking whether 12
is empty: it just doesn't mean anything. Even having it say "false"
suggests that "true" is possible. In general, I don't think
non-container objects should be declaring themselves "empty".

(John Carter) #19

I didn't go into detail there, John, but it's worth noting that
originally Codd thought that there should be several different NULL
values for relational databases. Later in life, he came to believe
that NULL values (both the single NULL value in SQL databases and
the multiple NULL values in his original relational papers) were
bad.

No, as I remember it, his problem wasn't with NULL, but rather the DB design.

ie. All instances where you have NotApplicable or NoThing null IN A DB TABLE can be refactored to a better relational design that didn't require them.

However, having factored the DB into more tables so neither variety of NULL occurred, there is still a need for NULL. There is still a need on occasion to construct reports for user display which are joins of various tables. And in those "views" there may be some fields are going to be NULL. And again, it is still necessary to disambiguate between NotApplicable and NoThing.

Your proposal of multiple types of nil makes life harder. Instead
of:

if foo.nil?
   # blah
end

I would have to do:

if foo.nothing? or foo.undefined? or foo.not_applicable?
   # blah
end

How about starting with the following in the core

class Object

# This is as is already
   def nil?
     false
   end

   def uninitialized?
     false
   end

   def not_applicable?
     false
   end

   def nothing?
     false
   end
end

class NilClass
   # No change here
   def nil?
     true
   end

   def to_s
     raise "No method, old definition inconsistent."
   end
end

class NoThing < NilClass
   def nothing?
     true
   end

   def empty?
     true
   end

   def to_s
     ""
   end

   def to_i
     0
   end
end

class NotApplicable < NilClass
   def not_applicable?
     true
   end
end

class Uninitialize < NilClass
   def uninitialized?
     true
   end
end

Now if the rest of the system chose the right version of nil when it assigned nil to something, the problem would go away and we can extend the NoThing in a sane harm free fashion.

The problem, as others have stated, is that adding #empty? to
NilClass implies a containment. I'd have as big a problem if we
added #empty? to Fixnum so that 0 returned true and everything else
returned false. (Indeed, would that be correct? Would -3.empty? be
true or false?)

Tut! Tut! I'm having this same problem with my son at school, they teach him the rote mechanics, but forget to teach the principles. (To be fair, I only started learning these things when I start reading foundations of mathematics type books from the university library...)

Come now, what is 3? 3 is 1+1+1. What do we mean by 1+1+1 we mean three contains a 1 and a 1 and a 1! So if I extract the contents of three I get 1 and 1 and 1 back.

And -3? Surprise surprise it contains three minus ones!

There is a strong overlap between core system design and axiomatic mathematics.

class FixNum
   def empty?
     self == 0
   end

   def length
     self
   end

   def each
     if self < 0
       # -3 contains three minus ones...
       (1..-self).each{|i| yield -1}
     else # And 3 contains three ones.
       (1..self).each{|i| yield 1}
     end
   end
end

John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : john.carter@tait.co.nz
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.

···

On Thu, 11 Aug 2005, Austin Ziegler wrote:

(David A. Black) #20

Hi --

The problem, as others have stated, is that adding #empty? to
NilClass implies a containment. I'd have as big a problem if we
added #empty? to Fixnum so that 0 returned true and everything else
returned false. (Indeed, would that be correct? Would -3.empty? be
true or false?)

I'd say it's undefined, or just meaningless. One could say that -3
"contains" three -1's... but I don't find that compelling. It could
be said, equally (and equally wrongly, in my view), to "contain" a 5
and a -8.

I don't consider something a container unless there's some meaning to
the concept of inserting, removing, counting, iterating over elements.
Even in the case of, say, a frozen array, there's still a meaning to
the concept of altering the collection. You can't remove a 1 from 3.
You can subtract 1 from 3, but that doesn't change 3. If it were
otherwise, then the expression "3 - 1" would turn 3 into 2, which
would cause lots of problems :slight_smile:

I would say that propagating the notion of emptiness to
non-collections definitely isn't the way to address nil-related
issues.

David

···

On Thu, 11 Aug 2005, Austin Ziegler wrote:

--
David A. Black
dblack@wobblini.net