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.