Check existence of object and it's property at the same time

C

Cory Patterson

I run into this from time to time and I was wondering if there is a
cleaner way to do check that an object is not nil and also check a
property of that object.

I want to do this:

if [email protected]? and @member.is_active?
... do something ...
else
... do something else ...
end

But this obviously raises a no method error if @member is nil.

I end up having to do:

if [email protected]?
if @member.is_active?
... do something ...
else
... do something else ...
end
end

I know it isn't that much more verbose, but does ruby have a more
elegant way of handling this?
 
D

David A. Black

Hi --

I've run into a similar situation before, and found that
short-circuiting in an 'if' statement is inconsistent.

For instance, this will short-circuit and prevent evaluation of
subsequent statements if the first one is false (which is desired
obviously):

unless creds.class.to_s =~ /Hash/ && creds.has_key?("user") && ...


But this won't:

unless creds.instance_of?(Hash) && creds.has_key?("user") && ...

They both short-circuit. Note that the puts("here") statement never gets
executed.
=> 1


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com
 
D

David A. Black

Hi --

Strange... it was failing before (like a few weeks ago) w/ a
NoMethodError on has_key? when it wasn't a hash. But trying it again
now works fine as you note.

Maybe you were doing has_key? first. Unless you did this:

h = {}
class << h; undef_method :has_key?; end

:)


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com
 
J

Jesús Gabriel y Galán

David,

You are completely correct. =A0I guess that was a bad example. =A0So the
order of the conditions is important:
NoMethodError: undefined method `is_active?' for nil:NilClass

Yes, it's important. Ruby starts evaluating from left to right, and
will shortcircuit on the first value that would make the whole
expression false (or true if it's an "or").

irb(main):004:0> member =3D nil
=3D> nil
irb(main):005:0> if member or member.is_active?
irb(main):006:1> puts "one or both were true"
irb(main):007:1> end
NoMethodError: undefined method `is_active?' for nil:NilClass
from (irb):5
from :0
irb(main):008:0> member =3D "test"
=3D> "test"
irb(main):009:0> if member or member.is_active?
irb(main):010:1> puts "one or both were true"
irb(main):011:1> end
one or both were true

Here you have the opposite situation: when the first truthy expression
is found, the evaluation is shortcircuited to that value, as you can
see that the is_active? method is not called in the last example.

Jesus.
 
R

Robert Klemme

2010/8/19 Jes=FAs Gabriel y Gal=E1n said:
Yes, it's important. Ruby starts evaluating from left to right, and
will shortcircuit on the first value that would make the whole
expression false (or true if it's an "or").

For the record: short circuiting also happens in Enumerable#any? and
#all?. And btw, the same short circuiting is done in Java and I guess
most modern languages.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top