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

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

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

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:

hi = "Hello"

=> "Hello"

defined?(hi)

=> "local-variable"

defined?(bye)

=> nil

def who; "World"; end

=> nil

defined?(who)

=> "method"

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

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

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

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

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

@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

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

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 Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

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