Simple Ruby question

Trying to do something simple in my view:

1: <% @rating = ratable.rating unless ratable.nil? -%>
2: <% @rating = rating unless rating.nil? %>

but whenever ratable is undefined, this fails with "undefined local
variable or method `ratable’ ". How can I check if a variable is
defined? Shouldn’t the .nil? do that for me?

More importantly, WHY does the .nil? not do that for me? To me,
‘nothing’, ‘undefined’, and ‘nil’ are the same…

On Feb 7, 2008, at 12:38 PM, kopf1988 wrote:

Trying to do something simple in my view:

1: <% @rating = ratable.rating unless ratable.nil? -%>
2: <% @rating = rating unless rating.nil? %>

but whenever ratable is undefined, this fails with "undefined local
variable or method `ratable’ ". How can I check if a variable is
defined? Shouldn’t the .nil? do that for me?

I do this kind of stuff all the time, and the only cases which result
in what you describe are those in which I don’t actually have the
local variable defined. Oftentimes, this occurs in a partial, but
I’ve done it elsewhere, too.

So referencing a non-existent variable will do it, but referencing a
variable set to nil will be fine.

Peace,
Phillip

On Feb 7, 2008, at 3:29 PM, Phillip K. wrote:

I do this kind of stuff all the time, and the only cases which result
in what you describe are those in which I don’t actually have the
local variable defined. Oftentimes, this occurs in a partial, but
I’ve done it elsewhere, too.

So referencing a non-existent variable will do it, but referencing a
variable set to nil will be fine.

Peace,
Phillip

Unlike instance variables, local variables don’t spring into existence
when referenced. If you’re trying to pass information between the
controller and a view, you can use instance variables which Rails
arranges to magically “copy” into the new view object that it
instantiates. If you don’t assign the variable, the it springs to
life in the view and has a value of nil.

If you really want to check, you can say:
@rating = ratable.rating if defined?(ratable) && ratable

which tells you something:

irb> hi = “Hello”
=> “Hello”
irb> defined?(hi)
=> “local-variable”
irb> defined?(bye)
=> nil
irb> def who; “World”; end
=> nil
irb> defined?(who)
=> “method”

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

defined?(ratable)

Exactly what I needed! Basically I have a rating on several objects,
and I pass ratable to the partial as a local, but I didn’t in some
cases apparently, and need it to be backwards compatible.

Thanks!

-Ryan

On 7 Feb 2008, at 20:43, Rob B. wrote:

defined? Shouldn’t the .nil? do that for me?
Phillip

Unlike instance variables, local variables don’t spring into existence
when referenced.

Or rather they spring into existence in a slightly weird way:
defined?(foo) #=> nil
if false then foo=123; end
defined?(foo) #=> ‘local-variable’

Fred

Hi guys,

just to muddy it a bit - but maybe help also - I use ||= a lot, so you
could put

ratable ||= nil

before the troublesome code and it would work fine

I also really like the nice way you can put || at the end of a
statement to set a default value

x = nil || ‘x’

So you can ensure that a variable will be set to a default value if
some method or other returns false or nil without a huge if and a lot
of verbiage. I think the code will be cleaner too.

I also really love being able to stick rescue on the end of lines …

HTH

On Feb 8, 9:20 am, Frederick C. [email protected]

On Feb 8, 2008, at 7:02 AM, ghoti wrote:

but whenever ratable is undefined, this fails with "undefined
So referencing a non-existent variable will do it, but
Or rather they spring into existence in a slightly weird way:
ratable ||= nil
of verbiage. I think the code will be cleaner too.

I also really love being able to stick rescue on the end of lines …

HTH

@Fred: Which is why my answer has:
@rating = ratable.rating if defined?(ratable) && ratable
it wants ratable to be defined and not be nil (or false)

Since ratable is only used in the context of an object being sent
the :rating method, there’s no hint whether it is a local variable or
a method on self.

@HTH: If you put: ratable ||= nil
ahead of the original line, you’d just get a NoMethodError when you
tried to call nil.rating

On Feb 7, 2008, at 10:24 PM, kopf1988 wrote:

Exactly what I needed! Basically I have a rating on several objects,
and I pass ratable to the partial as a local, but I didn’t in some
cases apparently, and need it to be backwards compatible.

Thanks!

-Ryan

@Ryan: Rather than kludge the partial, I’d strongly recommend that you
go back and pass in exactly what your partial needs to do the job
properly.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Hey bob

@HTH: If you put: rateable ||= nil
ahead of the original line, you’d just get a NoMethodError when you
tried to call nil.rating

you will?? If you leave the unless rateble.nil? on the end?

irb(main):006:0> rateable ||= nil
=> nil
irb(main):007:0> q = rateable.asdf unless rateable.nil?
=> nil

I did misspell rateable in the original post tho’.

On Feb 8, 2008, at 8:32 AM, ghoti wrote:

=> nil

I did misspell rateable in the original post tho’.

Well, no, not if you keep an ‘unless ratable.nil?’ or ‘if ratable’ on
the statement that calls ratable.rating. I thought you were saying
that with a ‘ratable ||= nil’ the problem was gone since ratable would
be defined.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

It is spelled ratable, not rateable. Dealing with ratings, not rates.

right now I’ve got this painful execution:

<% @rating = ratable.rating unless ratable.nil? if defined?(ratable) -
%>

Is there a standard is_defined_not_nil?(object) method… or will I
have to make one? (If I do make one, would it be best in the App.rb,
or App_helper.rb, because I’ll need it in many views likely).

-Ryan