Details
- Type:
Improvement
- Status: Open
- Priority:
Major
- Resolution: Unresolved
- Affects Version/s: None
- Fix Version/s: None
- Component/s: Repl / Interpreter
- Labels:None
Description
It would be very useful in some instances to be able to do something like "import{Predef.any2StringAdd => _}
" to hide predef implicits.
Activity
It works ONLY at the beginning of the file. In the example below, for instance, it won't compile with the first line uncommented, but will compile with it commented:
import Predef.{augmentString => _} // This works object Unimport { val x = "x" * 5 def main(args: Array[String]) { import Predef.{augmentString => _} // Here it doesn't work // import Predef.{wrapString => _} // This line doesn't make any difference, // here or at the beginning. It looks like a bug. Console.println("x" * 5) } }
We agreed on the last meeting that having such fine grained masking is in fact not correct, and allowing for having Predef import possibility at the beginning of the file is good enough. Unfortunately I don't remember the exact details now, but maybe Martin will want to add his 2 cents for completeness.
Closing to the previous state.
That's cool, but it's been on my list to make this work right in the repl and I have no ticket for it, so I'm going to commandeer this one this nobody's using it. I need to spot those masking imports and re-run them before every successive repl command for them to have any effect.
This is even more broken:
try to compile this:
import Predef.{intWrapper => _} object Test { println("test") }
Actually, I generally don't like the current behaviour for `import X.{bla => _}`. Right now this imports the symbol with a name (the underscore) not accessible in scope. This makes only sense if you use it in combination with a final wildcard import. Admittedly, this is as spec'd.
Or you use the syntax at the start of a file with Predef where seems to some special casing in the compiler at work. Is this specd somewhere?
Now if you use it in other cases, like when you've imported something in an outer scope and want to remove a symbol from inner scopes it doesn't work at all (and this is what this ticket is about) because renaming a thing in an inner scope doesn't remove it from the outer scope and because searches are done from inner to outer scope it is always found nevertheless.
I would propose a more general solution: `import X.{bla => _}
` really means 'make symbol inaccessible in this scope'. This would mean, the scope which is created by this import statement would have to filter all results from the outer scopes and remove results explicitly removed by the underscore syntax from the inner scope.
IMO this behaviour would feel more 'natural' than the current one and would play more nice with scoping in general. (If you copy-paste code into a scope and the pasted code contains the right imports you know it has the names it needs available. If pasted code instead removed things by `=> _` this removings may always be overridden by the outer scope in the current setting.)
My feeling is that, especially with implicits being bound to scope, finer grained control is needed in some cases.
This fix was floated last summer and works the same way with replating, viz, the predef imports are pulled to the top of the compilation unit.
apm@mara:~$ skala -cp "" Welcome to Scala! version 2.11.0-20131104-225025-6b780988ac (OpenJDK 64-Bit Server VM, Java 1.7.0_25). Type in expressions and I will evaluate them. Or try :help. scala> "hello".size res0: Int = 5 scala> import Predef.{ augmentString => _ } import Predef.{augmentString=>_} scala> "hello".size <script>:1: error: value size is not a member of String "hello".size ^
It works, with a slightly different syntax:
The output: