Don't overload #nil? in Ruby
paul.rosania.org
Don't overload #nil? in Ruby
1–10 of 40 posts
Re: Don't overload #nil? in Ruby
#2 if finished?
do_something
end
then finished? is not expected, and may not, return nil.If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write
if !some_value.nil? && some_value
do_something
end
In the end, these 'convenient' coercions that allow you to use any value as a boolean only come back to bite you, because unexpected stuff happens when stuff is unexpectedly nil. If it makes my coworkers cry that an object is nil and true at the same time, then they are at fault, not me.Edit: and more importantly (I forgot to point this out explicitly) a non-nil value != true. That any string or integer is 'true' can lead to very hard-to-find bugs.
Re: Don't overload #nil? in Ruby
#3Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
if some_value
do_something
end
It's a core expectation of the language that !!nil_thing == false, so why violate it?Re: Don't overload #nil? in Ruby
#4Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
Re: Don't overload #nil? in Ruby
#5Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
Re: Don't overload #nil? in Ruby
#6Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
What stuff should happen when something is unexpectedly nil if you tested it for truth-ishnes? Once you have written
if not some_value
something with some_value
end
the only things you can do with `x` are things you can do with `false`, which are not many.Re: Don't overload #nil? in Ruby
#7Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
Such code is everywhere in the Ruby community and explicitly endorsed by many. I have never seen code like your second example in the wild, and it's far more complicated than the idiomatic way of writing it: if some_value do_something end It's a core expectation of the language that !!nil_thing == false, so why violate it?
if !some_value
do_something
end
you often don't actually want it to be executed when some_value is nil instead of false. And when it is, you go scratching your head and searching where some_value came from, to discover some silly typo.In some ways, the reverse is even worse: when you write
if some_value
do_something
end
and you change some_value from nil to some sensible default like '', you will forget to update this clause and you will not understand why the code is being executed. If you use if !some_value.nil?
do_something
end
you don't have that problem, because the nil-test sticks out like a sore thumb.Re: Don't overload #nil? in Ruby
#8Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
You probably shouldn't use 'nil' to mean 'false', but since pretty much every compiler / interpreter out there will take the same branch when given a condition that's either nil or false, I'd say it's much safer to stick w/ what's existed for decades rather than accommodate some sort of tri-state boolean.
Re: Don't overload #nil? in Ruby
#9Conceptually, nil != false. You shouldn't use 'nil' to mean 'false'. You should always test explicitly for nil-ness using #nil?. If you write if finished? do_something end then finished? is not expected, and may not, return nil. If you expect some_value to be able to be nil (which, for boolean values, is hardly ever), you should write if !some_value.nil? && some_value do_something end In the end, these 'convenient' c…
IME using any value as boolean never caused me any problem, neither in ruby nor in other languages where the same is possible. What stuff should happen when something is unexpectedly nil if you tested it for truth-ishnes? Once you have written if not some_value something with some_value end the only things you can do with `x` are things you can do with `false`, which are not many.
if some_value
something with some_value
end
where you first use nil to signal false, but later change the base case of some_value from nil to 0, nil to NullObject or nil to some other base value. Since you think of these base cases as 'nothing', you will forget to change this related conditional the first time around, because it seems it would still do the right thing.Re: Don't overload #nil? in Ruby
#10Earlier quoted context omitted.
Such code is everywhere in the Ruby community and explicitly endorsed by many. I have never seen code like your second example in the wild, and it's far more complicated than the idiomatic way of writing it: if some_value do_something end It's a core expectation of the language that !!nil_thing == false, so why violate it?
Because when you write if !some_value do_something end you often don't actually want it to be executed when some_value is nil instead of false. And when it is, you go scratching your head and searching where some_value came from, to discover some silly typo. In some ways, the reverse is even worse: when you write if some_value do_something end and you change some_value from nil to some sensible default like '', you w…
Somehow this has never been a problem for me in eight years and hundreds of thousands of Ruby lines--but every programmer is different, and I'd like to hear other views.
change the base case of some_value from nil to 0, nil to NullObject
change some_value from nil to some sensible default like ''
What, what, what are you doing? Who uses an empty string to mean "uninitialized"? Nil and {0, "", etc) have very different semantic meanings. How would you discriminate between the default "" and a user-submitted ""? If you mean to check whether it has changed from the default, compare it to a default constant. If you mean to check emptiness, use #empty? or #blank?. I read these kinds of explicit .nil? checks as fighting the language, and in some ways, a violation of the cultural contract in Ruby and Lisp around truth charge.