Typo's in instance variable names can give confusing error messages

When you mistype an instance variable you get an error like:

undefined method `some_method' for nil:NilClass

which can be very confusing for a newcomer. I’m not saying we should reintroduce WhinyNils, but some DidYouMean like functionality would be really helpful.

That unfortunately is impossible, or close to impossible to implement.

However you can turn on Ruby’s verbose mode:

>> $VERBOSE = true
=> true
>> @foo.bar
(irb):5: warning: instance variable @foo not initialized
NoMethodError (undefined method `bar' for nil:NilClass)

I realise this is hard to do, but this confuses newbies all the time. It’s definitely something we’ve taken for granted as being unfixable.

1 Like

I like the idea of hooking into DidYouMean. Maybe there’s an opportunity for a PR there that monkeypatches nil? Or some other deeply ridiculous, deeply Rubyish thing that Just Might Work?

Maybe have actionview_precompiler look at the AST to find referenced ivars? https://github.com/jhawthorn/actionview_precompiler

1 Like

Looks like DYM has experimental support for ivars. We might be able to add a tracepoint for uninitialized ivars, but I know people commonly leave ivars uninitialized and disable warnings so it might be a perf hit for that code.

2 Likes

I made a PR for tracepoints on uninitialized ivars here. I will be very honest and say I haven’t thought of the consequences. It may break patterns like:

def foo
  @foo ||= "neat"
end
3 Likes

The OP example wasn’t clear to me, I guess it’s from something like @mistyped_ivar.some_method. I think using ruby -w or $VERBOSE = true or ruby -d is a good way to catch those.

I frequently see this as a problem in templates, as that’s where Rails prefers to use instance variables. I think it’s best to avoid them in the first place and always use a 2-line method to make accessor methods available from the controller to views: Alternative to Rails' sharing of instance variables between controller and views. · GitHub

Any typo will result in a more comprehensible “method not found” error.