anding statements.

K

Kyle Schmitt

This is odd, I was trying to use "and" to chain together some
statements, which I thought would work, but it ends up, it doesn't.

I tried "and", and was surprised that it didn't execute the second
half of the statement
I tried "&&" with some extra parenthesis just to see (although I was
pretty sure and was syntactic sugar for &&), and still no joy.
I tried "&", and it works with some statements, but not with return statements.
I know I can do this using a multi-line if, but I'm rather fond of
single line, sentence like statements.

I also tried "or", but that makes for slightly nonsensical statement,
so I'm leaving out that option.
#This works, but makes a cumbersome statement.
#puts "#{x} is divisible by two" or return false if x%2==0

It begs the question, just how does and work, if it doesn't continue
executing the right half of a statement, even when the left half was
fine?


Thanks,
Kyle


def something(x)
puts "#{x} is divisible by two" and return false if x%2==0
puts "#{x} makes me happy"
true
end

def something_different(x)
(puts "#{x} is divisible by two")&&(return false) if x%2==0
puts "#{x} makes me happy"
true
end

def something_that_doesnt_work(x)
(puts "#{x} is divisible by two")&(return false) if x%2==0
puts "#{x} makes me happy"
true
end

def something_longer(x)
if x%2==0
puts "#{x} is divisible by two"
return false
end
puts "#{x} makes me happy"
true
end
 
K

Kyle Schmitt

And no, I don't have a strange affinity for odd numbers, it was just
something to put there.
 
M

Michael Linfield

Consider the following:

x = 'word'
z = nil

test = x && z # test == nil
test = x and z # test == 'word'
test = (x and z) # test == nil

Regards,

- Mac
 
K

Kyle Schmitt

Mac,
If your two arguments were methods however, and the first one
succeeded, wouldn't you expect it to execute the second?
 
Y

Yossef Mendelssohn

Mac,
If your two arguments were methods however, and the first one
succeeded, wouldn't you expect it to execute the second?

The problem is that puts returns nil, which causes the boolean logic
to short-circuit and not even bother with the second.

I take that back. *A* problem is that puts returns nil. *The* problem
is that you're trying to do too much on one line.

if x % 2 == 0
puts 'even'
return false
end

It's possible to use 'and' and 'or' and post-condition (statement
modification) 'if' or 'unless' for clever flow control, but it often
turns out messier-looking than you think.

At least you weren't trying something like

x % 2 == 0 and puts 'even'
 
M

Michael Linfield

Kyle said:
Mac,
If your two arguments were methods however, and the first one
succeeded, wouldn't you expect it to execute the second?
Alright I'm going to attempt to explain this without confusing you or
myself.

Using '&' is basically comparing. It returns a value if not false.

1 & 2 #=> 0
2 & 2 #=> 2

Using '&&' is self evident.

"hey" && false
#=> false

"hey" && 10
#=> 10

true && false
#=> false

false && true
#=> false

Regards,

- Mac
 
R

Rolando Abarca

def something(x)
puts "#{x} is divisible by two" and return false if x%2==0
puts "#{x} makes me happy"
true
end

the problem here is that "puts" returns nil, so the && (and 'and')
will not reach the next part of the chain, because all of it resolves
to false:
something
=> nilsomething
=> nilsomething
something else
=> true

so you either re-def puts or use your own implementation of puts, like
I did in the example above.
regards,
 
T

Todd Benson

Alright I'm going to attempt to explain this without confusing you or
myself.

Using '&' is basically comparing. It returns a value if not false.

1 & 2 #=> 0
2 & 2 #=> 2

No! & is bitwise operator for Fixnum.

Todd
 
R

Rolando Abarca

Alright I'm going to attempt to explain this without confusing you or
myself.

Using '&' is basically comparing. It returns a value if not false.

1 & 2 #=> 0
2 & 2 #=> 2

AFAIR, '&' is a bitwise and operator:

1 & 2 -> 0 because 0b01 & 0b10 == 0b00
2 & 2 -> 2 because 0b10 & 0b10 == 0b10
1 & 3 -> 1 because 0b01 & 0b11 == 0b01

no boolean operations are done here.
regards,
 
K

Kyle Schmitt

Dohh! Puts returns nil.

That explains it. "and" and "&&" work like I expected, but puts doesn't.

I should have realized & was bitwise and. Interesting how it works
with nil though.

I'd rather not redefine puts just to write things in a certain way.


--Kyle
 
A

Adam Shelly

I should have realized & was bitwise and. Interesting how it works
with nil though.

This thread made me look up NilClass in the docs. I learned something new.
& is a method of nil, which always returns false.
nil & return(something)
doesn't work because the & method expects an argument, not a keyword...
I'd rather not redefine puts just to write things in a certain way.
I often do:
puts "error" or exit if condition
which reads a little funny, but it works and is concise.
(I hate reading code where the error handling takes up way more space than
the essential logic)

-Adam
 
R

Robert Klemme

Mac,
If your two arguments were methods however, and the first one
succeeded, wouldn't you expect it to execute the second?

No, because "and", "or", "&&" and "||" short circuit - for good reason!
This allows for safer and more efficient code. Consider

foo = ... # may be nil

foo and foo.do_something

If foo is nil you do not want #do_something to be invoked on it because
it will raise an exception. Also, it is not worthwhile to invoke it
because regardless of return value the expression will be false (because
foo is false).

Kind regards

robert
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top