Params[:user] && Params[:user][:name], Can We Make It Shorter?

Was talking with evan (Evan Phoenix) and hasmanyjosh (Josh Susser) in #caboose at too late of an hour, and came up with some code that may or may not be useful.

I frequently see code like this in Rails apps:

1
@name = params[:user] && params[:user][:name]
(actually Josh came up with that example)

Can’t just do “@name = params[:user][:name]” because params[:user] might be nil. Of course, we should be checking for nil values at some point earlier in the game, but nevertheless, this pattern seems common enough, so let’s see if we can do something fun with it.

If params[:user] is nil, we will get a too familiar exception:

1
2
3
4
>> @name = params[:user][:name]
NoMethodError: undefined method `[]' for nil:NilClass
        from (irb):2
>>

What happens if we define a method ‘[]’ on NilClass and have it return nil? Conceptually, doesn’t seem to hurt this case. In other cases, I’m not sure, I’ve only had it in my head for about 10 minutes.

1
2
3
4
5
class NilClass
  def [](*args)
    nil
  end
end

Now, using the same example above, we don’t get an exception:

1
2
3
>> @name = params[:user][:name]
=> nil
>>

In fact, we get the same result had we split the hash lookups with &&.

Useful? Scary? Not a good idea? Comments are welcome.

Comments