[Bug] !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 -

  identity is <%= identity.inspect %>
  !identity is <%= (!identity).inspect %>

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

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).

On Dec 7, 3:13 pm, Frederick C. [email protected]

On Dec 7, 5:35 am, Vikrant [email protected] wrote:

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

On 7 Dec 2008, at 17:19, Vikrant wrote:

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

It took me 4+ hours to figure out what went wrong and where (I’m not
complaining though).

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs