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 (De Morgan's laws - Wikipedia) 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