nil being empty

O

Ohad Lutzky

Show of hands - who thinks this is bad form?

class NilClass
def empty?; true; end
end
 
A

ara.t.howard

Show of hands - who thinks this is bad form?

class NilClass
def empty?; true; end
end

nil_is_not_a_container.push :bug if nil_is_not_a_container.empty?

-a
 
O

Ohad Lutzky

Ooh, actually it is bad form. Seeing as rails already defines .blank? to
be aliased to empty? for strings and arrays, and true for nils.
 
M

Martin Coxall

Show of hands - who thinks this is bad form?
class NilClass
def empty?; true; end
end

Can I wave a different body part at you to register my disgust?

Martin
 
D

David Chelimsky

Show of hands - who thinks this is bad form?

class NilClass
def empty?; true; end
end

Doesn't it depend on context? The other responders seem to suggest
that is objectively bad form, with which I can agree (generally), but
in a case like this:

collection.select do |item|
item.respond_to?:)empty?) and (!item.empty?)
end

I might prefer

collection.select do |item|
true unless item.empty?
end

or this (which, though more terse, I personally find less readable)

collection.select do |item|
!item.empty?
end

One of the beauties of the language (for me) is that language
invariants become somewhat less "in" and more "variant".
 
D

dblack

Hi --

Doesn't it depend on context? The other responders seem to suggest
that is objectively bad form, with which I can agree (generally), but
in a case like this:

collection.select do |item|
item.respond_to?:)empty?) and (!item.empty?)
end

I might prefer

collection.select do |item|
true unless item.empty?
end

or this (which, though more terse, I personally find less readable)

collection.select do |item|
!item.empty?
end

(Don't forget Enumerable#reject :)

But "empty" actually means something, and it doesn't apply to all
objects. (I mean, it *can*, if you define it, but it doesn't make
sense.) I wouldn't know whether any of these objects were or were not
empty:

10
98.6
String
lambda { puts "hi" }

etc. nil is in that category.


David

--
David A. Black | (e-mail address removed)
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
 
R

Rimantas Liubertas

Show of hands - who thinks this is bad form?
class NilClass
def empty?; true; end
end

My hand is up.
It is strange to ask "is your spoon empty?" when there is no spoon...


Regards,
Rimantas
 
J

Jim Crossley

Ohad Lutzky said:
Show of hands - who thinks this is bad form?

class NilClass
def empty?; true; end
end

FWIW, neither Ola Bini nor Martin Fowler consider it necessarily bad
form, depending on your context, i.e. whether it adds to or detracts
from the maintainability of your code.

See #7 here:
http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techniques.html

Or the pattern here:
http://www.refactoring.com/catalog/introduceNullObject.html

Odds are it is probably bad form and it's possible to encapsulate the
reason *why* you're testing for empty into a higher-level method of a
domain class upon which you truly could apply the pattern. Better
that domain class than the object, nil, I think.

Jim
 
F

Farrel Lifson

Doesn't it depend on context? The other responders seem to suggest
that is objectively bad form, with which I can agree (generally), but
in a case like this:

collection.select do |item|
item.respond_to?:)empty?) and (!item.empty?)
end

I might prefer

collection.select do |item|
true unless item.empty?
end

or this (which, though more terse, I personally find less readable)

collection.select do |item|
!item.empty?
end

One of the beauties of the language (for me) is that language
invariants become somewhat less "in" and more "variant".

You could make it slightly more elegant with an extra function call
collection.select.do |item|
!Array(item).empty? #Could also use !String(item).empty depending
on what item is
end

Farrel
 
T

Trans

Ohad said:
Show of hands - who thinks this is bad form?

class NilClass
def empty?; true; end
end

Put your hands down. Notice that everyone that says it's bad form is
doing so on purely ideological basis. I challenge them to show one good
_practical_ case where it's truly "bad". And no, purposefully expecting
a NoMethod error doesn't count --that IS bad form.

T.
 
A

ara.t.howard

Put your hands down. Notice that everyone that says it's bad form is doing
so on purely ideological basis. I challenge them to show one good
_practical_ case where it's truly "bad". And no, purposefully expecting a
NoMethod error doesn't count --that IS bad form.

hash_of_lists = Hash.new{|h,k| h[k] = new_list}
hash_of_lists[:key] << 42 if hash_of_lists[:key].empty?

-a
 
M

Martin Coxall

Put your hands down. Notice that everyone that says it's bad form is
doing so on purely ideological basis. I challenge them to show one good
_practical_ case where it's truly "bad".

You're working on the assumption that violating idiom or convention
isn't bad. As far as I'm concerned, it's very bad, because that's
where the root of many unpleasant and hard-to-find bugs lie.

My hand is staying up.

Martin
 
J

James Edward Gray II

You're working on the assumption that violating idiom or convention
isn't bad. As far as I'm concerned, it's very bad, because that's
where the root of many unpleasant and hard-to-find bugs lie.

Well said.
My hand is staying up.

I agree.

James Edward Gray II
 
D

David Chelimsky

Hi --



(Don't forget Enumerable#reject :)

But "empty" actually means something, and it doesn't apply to all
objects. (I mean, it *can*, if you define it, but it doesn't make
sense.) I wouldn't know whether any of these objects were or were not
empty:

10
98.6
String
lambda { puts "hi" }

etc. nil is in that category.

Agreed in general. But I'm thinking, ironically, of the NullObject
pattern applied, in this case, to nil. Admittedly, it is a stretch,
and I can't really make a great case for it (i.e. with an example I've
actually USED), but it seems to me that if I needed to evaluate items
in a collection for empty? and didn't care that maybe some process
somewhere inadvertantly added nil to the collection that this would be
a reasonable solution. Does that sound nuts? Am I asking for trouble?

David
 
D

David Chelimsky

I feel this being an unnecessary generalization.
Probably it is very often not the best way to treat the problem, but
it might as easily be the most elegant.
Instead of raising your hand David, please speak out ;)
Now it would be unfair to ask others for their wisdom without delivering my
own (as small as it might be).

If you define your small little NilClass monkeypatch above because you had
nils where you expected containers, guess what I think of your code ;)

Sometimes the code your code plays with is not your code.
 
J

Jeremy Henty

... in a case like this:

collection.select do |item|
item.respond_to?:)empty?) and (!item.empty?)
end

If the issue is simply that the collection might contain nils (rather
than some more general empty? things) I would just write

collection.compact.select do |item|
...
end

or

collection.compact.select do |item|
item && ...
end

Those examples only deal with a special case, but I've never needed to
implement anything more general. YMMV

Regards,

Jeremy Henty
 
D

David Chelimsky

Well said.


I agree.

Well, in spite of my previous arguments to the contrary, I'm going to
have to recind my down-hand and raise it high. Violating convention is
definitely problematic in my view. Thanks for bringing this up.

Cheers,
David
 
T

Trans

Put your hands down. Notice that everyone that says it's bad form is doing
so on purely ideological basis. I challenge them to show one good
_practical_ case where it's truly "bad". And no, purposefully expecting a
NoMethod error doesn't count --that IS bad form.

hash_of_lists = Hash.new{|h,k| h[k] = new_list}
hash_of_lists[:key] << 42 if hash_of_lists[:key].empty?

That's the best example I have yet seen. Thanks for that Ara. Yet
there's still a problem. Your expecting a NoMethodError on nil, just
like I said. That's the thing, there's no other possible issue involved
here. Now I'll grant James' concern that it can make some bugs harder
to track down, but if that's our primary concern then I suggest we get
back to static typing.

Consider further, that ANY EXTENSION WHATSOEVER can have the same
effect. If someone's class X defines #geegee and I add #geegee to
String, one can no long expect String to raise a NoMethodError on
#geegee. So I argue that the bad form is not in using nil.empty? BUt in
expecting such an error, and not addressing it properly.

hash_of_lists = Hash.new{|h,k| h[k] = new_list}
raise AProperError unless hash_of_lists[:key]
hash_of_lists[:key] << 42 if hash_of_lists[:key].empty?

T.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top