There is a Shadowed Implicit Value Members section in StringOps doc. E.g.:
def split(arg0: String, arg1: Int): Array[String]
Implicit information
This member is added by an implicit conversion from StringOps to String performed by method unaugmentString in scala.Predef.Shadowing
This implicitly inherited member is shadowed by one or more members in this class. To access this member you can use a type ascription:(stringOps: String).split(arg0, arg1)
Definition Classes
String
But when I try to run following program:
"aaa bbb ccc".split(" ", 2) //> res0: Array[String] = Array(aaa, bbb ccc)
Calling the String.split(arg0: String, arg1: Int)
doesn't need using type ascription as in the doc described.
So what is the Shadowed Implicit Value Members referring to? I tried to ask google but cannot find any reference.
Is it something like:
class A {
def foo() = println("foo")
}
class AOps(a: A) {
def bar() = println("bar")
def foo() = println("new foo")
def foo(i: Int) = println("foo %d".format(i))
}
object Program {
implicit def A2AOps(a: A) = new AOps(a) //> A2AOps: (a: A)AOps
val a = new A() //> a : A = A@15669ae
a.foo //> foo
a.bar //> bar
(a: AOps).foo //> new foo
a.foo(1) //> foo 1
}
Then the String.split(...)
and StringOps.split
function signatures are different, so there will no need be "type ascription".
Is this what "Shadowed Implicit Value Members" stands for? I'm a little puzzled. Thanks!
Normally the Scala compiler will look to perform implicit conversions when you call a method that doesn't exist for a given type:
case class Foo(x :String)
implicit class Bar(foo: Foo) {
def barOnly = "w00p"
}
println( Foo("test").barOnly )
Here when we call the method barOnly
on an instance of Foo
the scala compiler can see it needs to do an implicit conversion from Foo
to Bar
to provide us with that method and we get the expected output of w00p
. Try it
However if a method with the same signature exists in Foo
and Bar
, then we have some shadowing and the scala compiler will not do the implicit conversion unless we explicitly ask for it with type ascription:
case class Foo(x :String) {
def whoAmI = "Foo: " + x
}
implicit class Bar(foo: Foo) {
def whoAmI = "Bar: " + foo.x
}
println( Foo("test").whoAmI )
println( (Foo("test"): Bar).whoAmI )
The output is:
Foo: test
Bar: test
Try it
In your example of split
in the scaladocs, there are methods called split
on both String
and StringOps
, however they take different argument types, so I'm not entirely sure why the docs are warning us about having to use type ascription. We do not need to disambiguate anything for the compiler in this situation and type ascription has no effect:
import scala.collection.immutable.StringOps
val stringOps: StringOps = "aaa bbb ccc"
println( stringOps.split("a", 2).mkString )
println( (stringOps: String).split("a", 2).mkString )
The output for these two lines is identical:
aa bbb ccc
aa bbb ccc
Try it
Maybe just an error in the docs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With