Have a look at the following Scala example:
class A {
def foo(x: Int): Int = x
private class B {
def foo(): Int = foo(3)
}
}
The compiler produces an error message when trying to compile this:
A.scala:5: error: too many arguments for method foo: ()Int
def foo(): Int = foo(3)
^
For some reason the compiler doesn’t look in the enclosing class A to find the method to call. It only looks in class B, finds the foo method there that takes no parameters that doesn’t fit and then gives up. If I rename the methods, then it works without a problem:
class A {
def bar(x: Int): Int = x
private class B {
def foo(): Int = bar(3)
}
}
In this case, the compiler does look in class A and finds the bar method there.
Why does the first example not work; is this according to Scala’s specifications, or is this a compiler bug? If this is according to the rules, then why are the rules like this?
By the way, another way to get around the problem is by using a self type annotation:
class A {
self =>
def foo(x: Int): Int = x
private class B {
def foo(): Int = self.foo(3)
}
}
Technically the class B is a block. You could reduce the problem to the following:
That would cause the exact same problem. It is compliant to the specs, because all names introduced in a block shadow anything that has the same name (ignoring the signature, see chapter 2 of the spec). Overloading is only possible on class level. (chapter 6.26.3 in the spec)