I prefer that functions throw an exception when unable to do what they promised, rather than return nil or a null object. The try-catch block serves as documentation that the function might fail. If someone forgets to catch the exception, it will shut everything down rather than leave the program in an unanticipated state that could lead to an error elsewhere.
Don't overload #nil? in Ruby
21–30 of 40 posts
Re: Don't overload #nil? in Ruby
#22I'm not sure I like it, but this works def nil.method_missing(*args, &block); end So now you can call nil.whatever.you.like and get nil. It's also still falsy, but now every nil value in your app silently works and doesn't throw an error. It's both impressive and scary that Ruby lets you (or that new contractor you're not sure about) change the fundamentals of the language in one line of code.
In Objective-C nil will absorb any messages too, see the section "Sending Messages to nil" in http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/...
Re: Don't overload #nil? in Ruby
#23Having recently worked with a Ruby codebase where anything could be nil at anytime, I consider even references to nil to be a code smell. Developers are inherently prone to ignoring error handling, so they'll happily ignore the fact that Order#customer really means Order#customer_or_nil. And when they see errors in production, they'll slap an andand on it and call it fixed. The code becomes extremely difficult to rea…
Re: Don't overload #nil? in Ruby
#24Having recently worked with a Ruby codebase where anything could be nil at anytime, I consider even references to nil to be a code smell. Developers are inherently prone to ignoring error handling, so they'll happily ignore the fact that Order#customer really means Order#customer_or_nil. And when they see errors in production, they'll slap an andand on it and call it fixed. The code becomes extremely difficult to rea…
Scala's standard library provides very helpful information on how to replace null with its Maybe class (called Option in Scala). Just take a peek into their collections library[4], and search for Option.
[1] http://www.infoq.com/presentations/Null-References-The-Billi...
[2] http://moonbase.rydia.net/mental/writings/programming/monads...
[3] http://andand.rubyforge.org/
[4] http://www.scala-lang.org/api/current/scala/collection/immut...
Re: Don't overload #nil? in Ruby
#25Isn't this a flaw in Ruby, though? It also means that you can't create a delegate/decorator/proxy object for a false object and have it be false as well, which goes against the general "everything is determined by sending messages" vibe Ruby has going on. I know the reasoning (it's much faster to do math on object IDs than it is to call a method), but there are workarounds for this (e.g. only allowing frozen objects…
Re: Don't overload #nil? in Ruby
#26I'm not sure I like it, but this works def nil.method_missing(*args, &block); end So now you can call nil.whatever.you.like and get nil. It's also still falsy, but now every nil value in your app silently works and doesn't throw an error. It's both impressive and scary that Ruby lets you (or that new contractor you're not sure about) change the fundamentals of the language in one line of code.
I recall that this was the default action of Smalltalk? I can't find a reference though, so I am very likely incorrect. In Objective-C nil will absorb any messages too, see the section "Sending Messages to nil" in http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/...
Re: Don't overload #nil? in Ruby
#27I guess that overriding the behavior of any built-in classes in Ruby is not a great idea, as most gems rely on that unmodified behavior.
As a application creator, is is only bad when/if you open source part of it. Otherwise, you can always run the gems' tests against the compillation of your env.
Re: Don't overload #nil? in Ruby
#28Isn't this a flaw in Ruby, though? It also means that you can't create a delegate/decorator/proxy object for a false object and have it be false as well, which goes against the general "everything is determined by sending messages" vibe Ruby has going on. I know the reasoning (it's much faster to do math on object IDs than it is to call a method), but there are workarounds for this (e.g. only allowing frozen objects…
The ruby people will tell you that ruby's x, where x is power, flexibility, etc., comes from the ability to shoot yourself in the foot so just don't shoot yourself in the foot.
For example (and there are code smells in this, but it gets the idea across):
if account = Account.create(params[:account])
...
else
complainAbout account.errors
end
Truthiness should not be reserved for whether an object exists, it could also be used for whether it is valid, complete, or anything else.My particular example might not be a great one, but I think framework and library developers ought to be able to work a consistent use for truthiness and falseness into their creations, e.g. a true object has been saved, a true object is valid, a true object is complete, a true object represents the current state of the world instead of the past or future or a wrong state, and so forth.
Re: Don't overload #nil? in Ruby
#29Earlier quoted context omitted.
The ruby people will tell you that ruby's x, where x is power, flexibility, etc., comes from the ability to shoot yourself in the foot so just don't shoot yourself in the foot.
Speaking as a Ruby user, I think nil and the entire behaviour around truthyness and falseness are wrong. I should be able to create my own nil objects, and I especially would love to be able to create false objects that carry more information. For example (and there are code smells in this, but it gets the idea across): if account = Account.create(params[:account]) ... else complainAbout account.errors end Truthiness…
If you care enough about the state of what's being returned then it would be trivial to test if the returned object was of the class you were expecting (Account) and if not handle what it did return (some error indication) as appropriate.
Re: Don't overload #nil? in Ruby
#30Earlier quoted context omitted.
The ruby people will tell you that ruby's x, where x is power, flexibility, etc., comes from the ability to shoot yourself in the foot so just don't shoot yourself in the foot.
Speaking as a Ruby user, I think nil and the entire behaviour around truthyness and falseness are wrong. I should be able to create my own nil objects, and I especially would love to be able to create false objects that carry more information. For example (and there are code smells in this, but it gets the idea across): if account = Account.create(params[:account]) ... else complainAbout account.errors end Truthiness…
That said, I'm all for experimentation and would love to see this idea tried.