If you have a long chain of method calls, but want to check some
temporary values for nils, for instance to raise an exception,
currently the easiest way is with local variables:
e.g.:
def zipcode_for_user(user)
address = user.personal_data.address
raise 'no address!' unless address
address.zipcode
end
If "nil?" is extended to accept a block, and to return self (for
Object) and the result of the yield (for NilClass), the following
notation becomes possible:
user.personal_data.address.nil?{ raise 'no address!'}.zipcode
This is more concise, and (I think) also more readable. The flow of
the program isn't broken by the nil-check. Apart from raise
statements, it would make sense to use return statements in the
blocks.
The implementation is trivial:
class Object ; def nil? ; block_given? ? self : false ; end ; end
class NilClass ; def nil? ; block_given? ? yield : true ; end ; end
Do you think this is a good idea?
If you have a long chain of method calls, but want to check some
temporary values for nils, for instance to raise an exception,
currently the easiest way is with local variables:
e.g.:
def zipcode_for_user(user)
address = user.personal_data.address
raise 'no address!' unless address
address.zipcode
end
If "nil?" is extended to accept a block, and to return self (for
Object) and the result of the yield (for NilClass), the following
notation becomes possible:
user.personal_data.address.nil?{ raise 'no address!'}.zipcode
This is more concise, and (I think) also more readable.
Actually I am not sure about readability. Lines tend to grow pretty long that way. I would probably not use it. Also keep in mind that you will usually get an exception anyway since you're most likely calling a method that nil does not support.
> The flow of
the program isn't broken by the nil-check. Apart from raise
statements, it would make sense to use return statements in the
blocks.
The implementation is trivial:
... and probably slower than the current implementation as they add another boolean check.
class Object ; def nil? ; block_given? ? self : false ; end ; end
class NilClass ; def nil? ; block_given? ? yield : true ; end ; end
Do you think this is a good idea?
I am not so sure. But you can easily implement this with another method name so you don't have to change existing code's behavior. Also, nil values might be just only one reason to throw an exception so I am not sure about general usefulness.
Yeah, I know - I'm a conservative skeptic. 
Kind regards
robert
···
On 21.03.2007 13:51, Michiel de Mare wrote:
Michiel De mare wrote:
If "nil?" is extended to accept a block, and to return self (for
Object) and the result of the yield (for NilClass), the following
notation becomes possible:
user.personal_data.address.nil?{ raise 'no address!'}.zipcode
Why not use Object#tap?
user.p_data.address.tap {|a| raise "no address!" unless a}.zipcode
It's included in Ruby 1.9, is easily definable otherwise
(http://rubyurl.com/eG5\) and does basically what you want.
best,
Dan
···
--
Posted via http://www.ruby-forum.com/\.
Instead of interrupting the main flow of code with error handling, how about
this:
begin
zipcode = user.personal_data.address.zipcode
rescue NoMethodError => error
case error
when :personal_data then raise "No user!"
when :address then raise "No personal data!"
when :zipcode then raise "No address!"
end
In fact, thanks for spurring me to think of that technique, I think I'm
going to use it in future!
···
On 3/21/07, Michiel de Mare <merloen@gmail.com> wrote:
user.personal_data.address.nil?{ raise 'no address!'}.zipcode
--
Avdi
If your result set doesn't include 'false', then you can use 'or'. Mind you,
it gets ugly with the necessary brackets:
(user.personal_data.address or raise "no address!").zipcode
Especially if you go to multiple levels. It looks a bit too much like
LISP...
(((user or raise "no user!").
personal_data or raise "no personal_data!").
address or raise "no address!").zipcode
Regards,
Brian.
···
On Wed, Mar 21, 2007 at 09:55:07PM +0900, Michiel de Mare wrote:
If you have a long chain of method calls, but want to check some
temporary values for nils, for instance to raise an exception,
currently the easiest way is with local variables:
e.g.:
def zipcode_for_user(user)
address = user.personal_data.address
raise 'no address!' unless address
address.zipcode
end
If "nil?" is extended to accept a block, and to return self (for
Object) and the result of the yield (for NilClass), the following
notation becomes possible:
user.personal_data.address.nil?{ raise 'no address!'}.zipcode
I am not so sure. But you can easily implement this with another method
name so you don't have to change existing code's behavior. Also, nil
values might be just only one reason to throw an exception so I am not
sure about general usefulness.
I also doubt this would ever be useful. I like 'long lines' and hate
loads of 'if-statements' but I must admit I find them useful (or at
least, any other solution looks awful to me).
Why not using, let's call them "accessors?" which are "accessors with
a question mark".
Just by hacking with a bit of "method_missing" in both your class and
NilClass, this would not slow exec time much I guess, and the
implementation should also be trivial.
- in the class, you just send(accessor_name) when you get an unknown
accessor_name?
- in nilclass, you return "stuff" when having a '?' method (except
nil? or empty?)
The problem, IMHO, resides in the impossibility to return a coherent "stuff".
You *want* Ruby to NoMethodError you when you fail something.
You *can't* always know what you could prefer when your call fail.
Should "stuff" be nil, 0, empty string, new object ?
I suggest you use that in your project (if that's a big one) and then
tell us in a few weeks/months if that changed your life or not. If
that made your debugging harder.
Then again, this is a matter of personal preference I guess 
···
--
Sylvain Abelard,
Railer Rubyist. Epita MTI 2008.
No opinion on nil? but there are a couple examples of ?-methods
with blocks in core: any?, all?.
Gary Wright
···
On Mar 21, 2007, at 9:04 AM, David A. Black wrote:
No, I don't like it. It's unidiomatic for a ?-method to take a block,
Agreed. However, the methods you mention use the block in order
determine whether the predicate is satisfied or not. The action bit
is still just returning true or false.
The proposed 'nil?' uses the block to dispatch some unrelated
behavior, and it doesn't return a boolean. I agree with David, et al.
on this one.
···
On 3/21/07, Gary Wright <gwtmp01@mac.com> wrote:
No opinion on nil? but there are a couple examples of ?-methods
with blocks in core: any?, all?.
--
Lou.