Strange problem with "and" - "&&"

Hello

I have a strange problem with this code:

<%unless (@students.empty? and params[:commit].nil?) %>
<%="test"%>
<%= render :partial => 'results' %>
<% end %>

Even though in some cases @students.empty? returns false and params
[:commit].nil? returns true (or the opposite), it displays the test
and the render area.

I put before and after the code the <%=params[:commit].nil?%> and <
%=@students.empty?%> so I can see it (it shows false and true or the
opposite and always it shows the render area and the test). I also
tried && but it was the same problem.

The only way it worked was this:

<% unless @students.empty? %>
<% unless params[:commit].nil?%>

      <%="test"%>
<%= render :partial => 'results' %>

<% end %>
<% end %>

So why "and" - "&&" doesn't work? I tried every combination with () or
without ()...

Thank you

Hello

I have a strange problem with this code:

<%unless (@students.empty? and params[:commit].nil?) %>
<%="test"%>
<%= render :partial => 'results' %>
<% end %>

[snip]

The only way it worked was this:

<% unless @students.empty? %>
<% unless params[:commit].nil?%>

I think you have some misunderstanding when it comes to boolean logic
- Your code that works is just fundamentally different to the first
snippet you showed.

unless a
  unless b
   ...
  end
end

is equivalent to if !a && !b

but

unless a && b
...
end
is equivalent to if !( a && b) which in turn is equivalent to !a || !
b (see de morgan's laws)

Fred

Change it to || (or).

Try this in IRB:

puts "Render" unless(true && false) # Prints Render

puts "Render" unless(true || false) # Does not print
puts "Render" unless(false || true) # Does not print
puts "Render" unless(true || true) # Does not print
puts "Render" unless(false || false) # Prints render (which is what
you want)

Quoting Yiannis <istoselidas@gmail.com>:

Hello

I have a strange problem with this code:

<%unless (@students.empty? and params[:commit].nil?) %>
<%="test"%>
<%= render :partial => 'results' %>
<% end %>

unless both conditions are true, render the partial

the equivalent is:

if !@students.empty? || !params[:commit].nil?

I suspect you want an 'or" instead of the 'and' in the 'unless'. I.e. unless
either condition is true, render the partial.

unless @students.empty? or params[:commit].nil?

equivalent:

if !@students.empty? and !params[:commit].nil?

or:

if !@students.empty? and params[:commit]

so the partial will be rendered if both there are students and params[:commit]
exists and is non-nil.

I personally have stopped using 'unless' with complex arguments entirely and
am using it even with simple arguments less.

Lookup De Morgan’s Theorem (http://en.wikipedia.org/wiki/De_Morgan’s_theorem)
and tattoo it on your arm or commit it to memory.

HTH,
  Jeffrey

Oops! Yes indeed I need an "or" instead of "and", how I missed
that?? :slight_smile: Thank you all for your help and the advices!

I think Jeffrey is right, "unless" with complex logic is just too
difficult for most of us to get our brains round easily. I avoid it
except in trivially simple cases.

Colin

You just insulted thousands of Perl programmers.

But seriously.. it's just the opposite of "if".

Easy is the opposite of Difficult :slight_smile:

Maybe I should not have said 'most of us' but certainly it applies to
me. There is a similar problem with variables with names like
not_valid, it is too easy to overload the brain when included in a
logical expression.

Colin

It took me a couple of minutes to decide, but +1

Colin