!nil returns false for partial instance variable in specific conditions.

Hi,
If we call a partial with a name such that there also exists a
instance variable with the same name (ex: @identity) in the controller
then passing :object => nil to render() and calling (!
identity).inspect in '_identity.html.erb' prints false while
identity.inspect prints nil.

Here is a more specific description -

Let there be a controller named Check.

class CheckController < ApplicationController
  def index
    @identity = nil
  end
end

views/check/index.html.erb contains -
<%= render :partial => 'identity', :object => nil %>

views/check/_identity.html.erb contains -
<pre>
  identity is <%= identity.inspect %>
  !identity is <%= (!identity).inspect %>
</pre>

calling localhost:3000/check/ prints -
  identity is nil
  !identity is false

NOTE:
1. There must be a controller instance variable with the same name as
of partial.
2. I have been able to trace the problem down to between line 31 and
42 of file
http://github.com/rails/rails/tree/dc0411fad78bfc92fe92dc88bbad726eb4d1a883/actionpack/lib/action_view/renderable_partial.rb

I'm using -
Rails 2.2.2
Ruby 1.8.6 (2007-09-14 patchlevel 111) [i386-mswin32]
RubyGems 1.3.1
Windows XP Home Ed. SP3

I've also uploaded a sample app folder at
http://code.google.com/p/googol/source/browse/?r=95#svn/lab/learning/ruby-bug-on-!nil/app/controllers

- thanks

Hi,
If we call a partial with a name such that there also exists a
instance variable with the same name (ex: @identity) in the controller
then passing :object => nil to render() and calling (!
identity).inspect in '_identity.html.erb' prints false while
identity.inspect prints nil.

The key here is http://github.com/rails/rails/commit/acbf2b74aa3001fb6064bba96cd0033495774357

What is being deprecated is render :partial => 'foo' automatically
taking the value of @foo.
The way that this is done is that the foo object in your partial is
actually a tiny proxy object. If you try and do anything with that
object it will just pass it on to the real object (and print a small
deprecation notice - you should see these in your logs).
Ruby being ruby, ==, inspect, class etc... can all be passed on to the
target objects - they are just method calls after all.
That is not true of ! though, which just flips nil/false to true and
everything else to false and so you get the behaviour you demonstrate.

Fred

Yes, that might be the "reason" (though not technically strong enough
to understand that proxy thing), but still I find it as a bug. It just
breaks the common assumptions (assumption is perhaps wrong word, it
breaks just how it must work). nil is after all "not true" (and so is !
nil).
It took me 4+ hours to figure out what went wrong and where (I'm not
complaining though).

Yes, that might be the "reason" (though not technically strong enough
to understand that proxy thing), but still I find it as a bug. It just
breaks the common assumptions (assumption is perhaps wrong word, it
breaks just how it must work). nil is after all "not true" (and so is !
nil).

Short version is that the thing that looks like nil isn't actually nil
What it's trying to tell you is that having @identity magically assigned to identity in partials called identity is deprecated

Fred