Skip to content

Instantly share code, notes, and snippets.

@vrinek
Last active August 29, 2015 14:13
Show Gist options
  • Save vrinek/216d8c621c130c1fd70f to your computer and use it in GitHub Desktop.
Save vrinek/216d8c621c130c1fd70f to your computer and use it in GitHub Desktop.
Ruby 2.2 - Warning: circular argument reference

Ruby 2.2.0 now warns against a circular argument reference. It is pretty simple to demonstrate and pretty difficult to explain so I'll just present some code snippets.

The first example shadows a function (which I have encountered in one of the open-source projects I'm involved with):

def foo
  42
end

def bar(foo = foo)
  foo
end

puts bar.inspect

On ruby 2.1 it just prints 42. On ruby 2.2 though:

-e:5: warning: circular argument reference - foo
nil

The warning refers to the def bar(foo = foo) definition. If you remember a = a with a being an uninitialized variable, initializes a with the value of nil. Ruby 2.1's function definitions though was not fully following this logic and that disparity was utilized by some developers as a feature. Now in ruby 2.2 this has been fixed and recognized properly.


Similarly when shadowing a variable:

foo = 42

def bar(foo = foo)
  foo
end

puts bar.inspect

On ruby 2.1 it fails with:

-e:3:in `bar': undefined local variable or method `foo' for main:Object (NameError)
        from -e:1:in `<main>'

But on ruby 2.2, it recognizes the circular reference:

-e:3: warning: circular argument reference - foo
nil

To figure out if one's code exploits this feature/bug, one can simply run the following regexp:

ag 'def +[A-Za-z._]+(\(| +)([^)]+, *)?([a-z_]+) *= *\3[^a-z_.]'

I'm assuming using The Silver Searcher and not filtering any files based on extension. Otherwise, just replace ag with git grep and you are good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment