Hi everyone, It seems like every time I want to evaluate a possibly undefined variable I have to use defined? to see that it exists first, so I can't simply have -- if params[:range_start] > 3 or something like it. I need to have -- if defined? params[:range_start] && params[:range_start] > 3 I can't even have -- if params[:range_start].nil? This is really annoying - is there anyway to avoid this? Thanks, Daniel H.
on 2006-04-16 07:23
on 2006-04-16 08:08
On 4/15/06, Daniel H. <firstname.lastname@example.org> wrote: > > I can't even have > > -- if params[:range_start].nil? > > > This is really annoying - is there anyway to avoid this? > You can do things like this: a = 1/0 rescue 5 Which is particularly handy when you're calling a method on something that might be nil, and you can't easily deal with it in another way. However, given the particular example you used.. are you sure you're having the problem you think you have? In a Rails controller action, you're always going to have 'params'.. so you only need to deal with the issue of a particular missing parameter. if params[:range_start] || 0 > 3 stuff end Since the default value of the hash is nil, that will evaluate to "if 0 > 3"
on 2006-04-16 08:12
On Apr 15, 2006, at 08:22 PM, Daniel H. wrote: > It seems like every time I want to evaluate a possibly undefined > variable I > have to use defined? to see that it exists first, so I can't simply > have I can honestly say that I've never actually made a call to defined?, in all the Ruby code I've written in the last 10+ months... > -- if params[:range_start] > 3 This can be: if params[:range_start].to_i > 3. Using the to_i method will return zero if :range_start isn't in the params hash. > or something like it. I need to have > > -- if defined? params[:range_start] && params[:range_start] > 3 If you want to go this way, you could simply say: if params[:range_start] && params[:range_start] > 3, but that's far more verbose than you need to be. > I can't even have > > -- if params[:range_start].nil? This works for me, on every Hash object I've ever tried it on. Are you getting an exception when you do this? > This is really annoying - is there anyway to avoid this? I'm thinking you're doing something that's not quite right. The behavior you're describing goes against everything I've seen, with regard to how Ruby Hash objects work. -Brian
on 2006-04-16 08:27
I apologize if this is a very newbified response, but when I try something like the example you gave, I get: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occured while evaluating nil. The code in my controller is: unless (params[:search][:starting_city_id] || 0 < 1) || (params[:search][:destination_city_id] || 0 < 1)
on 2006-04-16 08:33
On Apr 15, 2006, at 09:25 PM, Daniel H. wrote: > (params[:search][:destination_city_id] || 0 < 1) OK. That error is actually telling you that params[:search] is nil. You can't access a nil object as though it were a Hash or Array, so if params[:search] is nil, you would be saying nil[:starting_city]. Make sure you look at the debug output of the params object, which is also present on that page. You'll likely see that there's no sub-hash with a key of "search". Also, I would actually recommend doing my to_i transformation on the object you want from params. Not only will this remove the need for using "x || 0 < 1", it's a good idea to make sure you are working with integers on both sides of the comparison. All scalar values in the params hash are strings when they get to your controller. This is a quirk of the way HTML post data is encoded and sent in the HTTP request... -Brian
on 2006-04-16 08:51
Right, there isn't a sub-hash with key of "search". Is there anyway to evaluate params[:search][:starting_city_id].to_i < 1 without using defined? and without getting an error in the instances when params[:search] is nil? In this particular case it's not absolutely necessary to group :starting_city_id and :destination_city_id in the :search hash , I just like to keep related variables together like that. Am I just coding ineffectively?
on 2006-04-16 09:24
You have more or less complete control over what appears in your controller's params object. The primary reason you would have params [:search][:starting_city] is if you have a field in the form of the page that calls the controller you are in, whose name attribute is "search[starting_city]". If you don't, then you need to either fix the form being submitted, or fix your controller code to reference objects that should be in params. Testing for params[:search} seems to be counter-intuitive, when you should be looking take control of what data is being submitted to your controller, before start trying to post-process the submitted data. If there's a legitimate reason for params to sometimes not have a [:search] key, then I recommend wrapping a conditional around that fact: if params[:search] ... end unless params[:search].nil? ... end -Brian
on 2006-04-16 10:13
Testing for definition is the "correct" thing to do because you've already forseen that it could be undefined. However... you might try using an exception: params[:search][:starting_city_id].to_i < 1 rescue nil If your params[:search] is undefined, you will get a NameError exception and the expression will evaluate to nil. Just a thought -- View this message in context: http://www.nabble.com/tired-of-using-defined-all-t... Sent from the RubyOnRails Users forum at Nabble.com.
on 2006-04-16 10:47
On 4/16/06, Brian V Hughes <email@example.com> wrote: > You have more or less complete control over what appears in your > controller's params object. Only for well behaved users who are using the forms you send to their browser.
on 2006-04-16 12:15
Thanks everyone for your input. It looks like it's just not possible to have something like, some[:multi][:dimensional][:hash].to_s without checking that each dimension along the way exists, or without rescuing the operation, unlike in PHP (shudder) where you can have something like if($_POST['search']['cabarets']) blah blah blah Though I guess I COULD do this without worrying about it by extending Nil to have  return a nil object. Thanks again fellas!
on 2006-04-16 17:18
How about a helper? if_params(:search,:cabarets) #do stuff here end I am no Ruby expert, but I am certain you could set up your helper to work for any depth array and check for nils the whole way down. If if_params is to long, you could shorten it to ifp or something similar.
on 2006-04-16 23:08
On Apr 16, 2006, at 1:15 AM, Daniel H. wrote: > > if($_POST['search']['cabarets']) blah blah blah > > Though I guess I COULD do this without worrying about it by > extending Nil to > have  return a nil object. > Please don't do that! You will run into all kinds of weird problems if you start defining methods like that on NilClass. -Ezra
on 2006-04-16 23:33
Lol ok! Thanks for your help!