Getting a reference to an external function parameter with a conflicting name

Please review this code:

trait A { def a : Int } def f ( a : Int ) = { def a0 = a new A { def a = a0 } } 

The problem is quite obvious: def a0 = a is a typical annoying code template, and the situation only gets worse when more parameters are entered.

I am wondering if it is possible somehow to get a direct reference to the variable a external area inside the declaration of the instance of the attribute and, thus, get rid of the intermediate a0 .

Please keep in mind that changing the name of the input parameter of the function is not allowed, since changing the property.

+5
source share
3 answers

I don’t think there is a direct way to do this because it will require some special (hypothetical) identifier thisMethod . However, depending on your context, the following two ways are possible to avoid name shadowing:

(1) Replace the anonymous class A with the implementation class:

 case class AImpl(a: Int) extends A def f(a : Int): A = AImpl(a) 

(2) Define f in an abstract attribute and use a specific implementation for it:

 trait F { def f(a: Int): A } object FImpl extends F { def f(a0: Int): A = new A { val a = a0 } } def test(factory: F): A = factory.f(a = 33) 
+4
source

I think the closest you can go (without changing your API):

 def f(a: Int) = { def ff(a0: Int) = { new A { def a = a0 } } ff(a) } 

In Scala, methods are not types. Thus, it is not possible to refer to them with a type system or with any of the members.

 scala> class X{def f = 0} defined class X scala> import reflect.runtime.universe._ import reflect.runtime.universe._ scala> typeOf[X].member(newTermName("f")).isType res9: Boolean = false 
+3
source

Here is an anonymous solution.

 package eyeshadow trait A { def a: Int } class B { def f(a: Int) = { val fa: A = new { //private val b = a private[this] val b = a // crashes, sorry scalac. edit: ok in 2.11 } with A { def a = b } fa.a /* * This seems far-fetched, but compare the initial objections in * https://issues.scala-lang.org/browse/SI-3836 * All I want is to alias a symbol, right? * Maybe the override means "do not shadow." val fa: A = new A { //import fa.{ a => b } import this.{ a => b } override def b = a } */ } } object Test { def main(args: Array[String]) { val b = new B println(bf 7) } } 
+3
source

Source: https://habr.com/ru/post/974788/


All Articles