Skip to content

Binding of generic types #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jendakol opened this issue Jul 31, 2017 · 5 comments
Closed

Binding of generic types #65

jendakol opened this issue Jul 31, 2017 · 5 comments

Comments

@jendakol
Copy link

I have issue with binding some generic types, namely bind[Unit => String] and bind[(=> Unit) => String]. Guice itself is able to both bind and inject types like this, but current implementation of this library stops me from doing that, because:

  • bind[Unit => String]
    Unit is converted to Void, but only for binding thus the binding is not found when injecting
  • bind[(=> Unit) => String]
    (=> Unit) => String is in fact Function1[Function0[Unit], String] but compiler is unable to generate Manifest for that

I would like to ask if there is some reason why the Unit is converted to Void.
I would be very happy to fix it (it's easily solvable by a short macro which I already wrote for myself as a workaround), I just want to be sure there's not some good reason for having it like these.

Thx.

@tsuckow
Copy link
Member

tsuckow commented Aug 4, 2017

I can't think of a good reason. Every so often I try to fix some of these more nuanced issues but it inevitably triumphs over me.

PR's welcome.

@jendakol
Copy link
Author

jendakol commented Aug 4, 2017

OK, I'll do my best.
But are you aware it will not be 100% compatible with the current version? I doubt there's a lot of people using it, but injecting the java.lang.Void => T will stop work, will be replaced by Unit => T (which was original binding). Thus, it will be necessary to raise version of this library but that will break you same as Guice versioning scheme... Just wanted to warn you :-)

@tsuckow
Copy link
Member

tsuckow commented Aug 17, 2017

I don't know that I ever claimed to be semver. There is also the argument about whether fixing an unexpected behaviour is "breaking".

@tsuckow
Copy link
Member

tsuckow commented May 28, 2018

I think with changes in 4.2.1 this is now "fixable." But I am having a hell of a time making a test case. I tried

 "allow binding by name to Unit" in {
      val foo:(=> Unit) => String = (a) => "dog"
      val module = new AbstractModule with ScalaModule {
        override def configure() = {
          bind[(=> Unit) => String].toInstance(foo)
          bindInterceptor[AOPI](methodMatcher = annotatedWith[AOP])
        }
      }
      import net.codingwell.scalaguice.InjectorExtensions._
      val injector = Guice.createInjector(module)
      val func = injector.instance[(=> Unit) => String]
      func shouldEqual foo
    }

But this results in [info] - should allow binding by name to Unit *** FAILED ***
[info] java.lang.ClassNotFoundException: scala.
[info] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[info] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[info] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[info] at java.lang.Class.forName0(Native Method)
[info] at java.lang.Class.forName(Class.java:348)
[info] at scala.reflect.runtime.JavaMirrors$JavaMirror.javaClass(JavaMirrors.scala:555)
[info] at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$classToJava$1.apply(JavaMirrors.scala:1211)
[info] at scala.reflect.runtime.JavaMirrors$JavaMirror$$anonfun$classToJava$1.apply(JavaMirrors.scala:1203)
[info] at scala.reflect.runtime.TwoWayCaches$TwoWayCache$$anonfun$toJava$1.apply(TwoWayCaches.scala:49)
[info] at scala.reflect.runtime.Gil$class.gilSynchronized(Gil.scala:19)

Which I assume is meaning foo isn't valid. It may also be due to me attempting to use TypeTag to determine the type.

@tsuckow
Copy link
Member

tsuckow commented Jun 23, 2020

I fiddled with this again and made 1 tweak in 4.2.8 that Unit didn't seem to be getting typed correctly.

However it seems the the reflection to find a Java type for (=> Unit) results in a class not found error of <byname>. I can see that the Symbol is for => T0 but not sure how to coerce that to classOf[Function0]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants