Check variable defined and not nil

Does anyone know of a way to write a function (or the name of an existing function?) that will both check if a variable is defined, and ensure that it is non-nil?

This has to be an uber-common problem, but hard to figure out the right Google term for.

Situation: I have partials that use optional local variables. If an optional variable is not passed in, and has never been passed in since my mongrel instance started, then defined?(variable) will be false. However, if the partial has ever been called before, the local variable has the value of "nil" (even if it wasn't passed in on this call), so defined?(variable) will be true.

Thus, I am left with ugly code (defined?(variable) && variable) littered throughout my partials.

What's worse, I can't seem to write a method to combine these two checks because I get an error in my partial when I try to call a method with a variable that isn't defined. Bleck.

Ideas?

Bill

Hi --

I could, but that would be putting extra responsibility on the caller. I guess that a decent option would be to have an options hash for the optional options, and just pluck the variables out of there, so options[:variable] will always be defined, just as nil.

That wouldn't be an awful solution, but it would only work for partials, and I'm pretty sure someone out there knows a better way...

B

Does anyone know of a way to write a function (or the name of an existing function?) that will both check if a variable is defined, and ensure that it is non-nil? This has to be an uber-common problem,

Not that common, but I've encountered it :slight_smile:

: : Ideas?

Might not be what you're looking for but at least it's shorter,

  (variable rescue nil)

You're probably aware, that defined? is not an ordinary function: http://redhanded.hobix.com/inspect/methodCheckDefined.html So addressing the problem directly without built-in support looks unlikely.

Stephan

Interestingly, I'm running into this same problem.

I discovered a fascinating fact. The rescue only happens the very first time for that partial. Page reloads or other calls to the partial on the same page somehow make the local variable defined. I can understand multiple calls on the same page I guess (maybe "local" is scoped for the whole view?) but on reloads?

Anyway, I had a simple test partial that looked like this:

[code] <h1><%= (text || "DEFAULT") rescue "RESCUED DEFAULT" %></h1> [/code]

And in my view I have the following:

[code] <%= render :partial => 'test' %> <%= render :partial => 'test', :locals => {:text => "LOCAL TEXT" }%> <%= render :partial => 'test' %> <%= render :partial => 'test', :locals => {:text => "ANOTHER LOCAL TEXT" }%> [/code]

If I run it from a freshly started server, I get:

RESCUED DEFAULT LOCAL TEXT DEFAULT ANOTHER LOCAL TEXT

and if I simply reload the page (either reload or shift-reload), I get:

DEFAULT LOCAL TEXT DEFAULT ANOTHER LOCAL TEXT

Which tells me that the rescue truly only happens the very first time. Weird.

Anyway, by combining a default and a rescue, I think you can do what you need, mainly: have a partial with some default functionality that can be overridden by locals and then do the right thing whether the local variable is nil or undefined.

For me, this is really useful to know because I have some partials that render logos via attachment_fu using a default sized thumbnail. Then, I can set it so I can pass in a different thumbnail size as a local and it'll use that instead. Whee!

-Danimal

Here's the solution that I use to set a default value for a partial local variable if one is not passed by the calling view.

Add something like this to the start of your partial: [code] <%- if local_assigns[:local_variable_name].nil? then local_variable_name = your_default_value end -%> [/code]

You could probably clean it up a bit, depending on your ability to read Ruby: [code] <%- local_variable_name = your_default_value if local_assigns[:local_variable_name].nil? -%> [/code]

- GG Crew

What’s wrong with:

your_variable ||= “Default”?

Hi     Is there anything wrong with   <% if !defined? variable_name%>