Casting after comparison of two Array manifest in scala

I have some problem to cast my objeсt Variable[A] where A <: Array[_]

I create a function to compare manifest and cast data into Array to the good type.

My object Variable[A] store a Manifest[A] into the def 'type'

I make a plugin of an existent software, so it's not me which instanciate this Variable with good type.

Prototype object and class :

object Prototype {
  def apply[T](n: String)(implicit t: Manifest[T]) = new Prototype[T] {
    val name = n
    val `type` = t
  }
}

trait Prototype[T] {
  def name: String
  def `type`: Manifest[T]
}

Variable Object and Class :

object Variable {
  def apply[T](p: Prototype[T], v: T) = new Variable[T] {
    val prototype = p
    val value = v
  }
}

trait Variable[T] {
  def prototype: Prototype[T]
  def value: T
}

My class which use :

class XYDataReader[A <: Array[_]](var data: Iterable[Variable[A]]) {

    def get[T](variable: Variable[A])(implicit m: Manifest[T]): Option[T] = {
        if (variable.prototype.`type` <:< m) {
          Some(variable.value.asInstanceOf[T])
        } else {
          None
        } 
}
}

There is probably a mistake of my part when i instanciate Variable object used to compare, so i give also the code of instanciation :

val v:List[Any] = List[Any](1.2,2,3)
val p = Prototype[Array[Any]]("col1")
val myVariable = Variable(p, v.toArray(ClassTag(p.`type`.runtimeClass)))

I don't understand why pattern matching failed when i call get[Array[Double]](myVariable) where myVariable.value contain an Array[Double]

When i println() the two manifest :

  • variable array type : Array[double]
  • m type : Array[Double]

It seem an Array[Double] is not an Array[double], how can i resolve/cast this ?

Answers


This started out as a comment, since it's not an answer, but it's too big and needs formatting (plus my browser tab's auto-reload caused it to be lost the first time...)

So... For starters, your snippet of code is incomplete and / or incorrect. Potentially there are imports in effect which could alter the meaning of that code. Secondly, as shown it would not compile 'cause what appears to be a formal type parameter, the A has no binding. Thus unless you have an actual type named A that won't compile.

Secondly, Double is potentially ambiguous. There is both scala.Double and java.lang.Double and they are distinct. Scala auto-boxes and -unboxes primitive types for you, typically when they're used to instantiate type parameters for generic methods (and specialization is not used). A consequence of this is that Array[scala.Double] is distinct from Array[java.lang.Double]. Scala will create arrays of primitive types when possible, but Array[java.lang.Double] is explicitly an array of boxed double-precision floating point.

E.g.:

scala> val d1: scala.Double = 123.456
d1: Double = 123.456

scala> val d2: java.lang.Double = 234.567
d2: Double = 234.567

scala> d1.getClass
res25: Class[Double] = double

scala> d2.getClass
res26: Class[_ <: Double] = class java.lang.Double

scala> val ad1: Array[scala.Double] = Array(123.456, 234.567)
ad1: Array[Double] = Array(123.456, 234.567)

scala> val ad2: Array[java.lang.Double] = Array(234.567, 345.678)
ad2: Array[Double] = Array(234.567, 345.678)

scala> ad1.getClass
res27: Class[_ <: Array[Double]] = class [D

scala> ad2.getClass
res28: Class[_ <: Array[Double]] = class [Ljava.lang.Double;

So please, if you would, fill in the missing details of your sample code?


Finally, with help of colleague methods to resursively unArrayify Array, i resolve my runtime type reification problem. Now i can compare equality between Array[double] with Array[Double].

  // Convert unknow A en Array[T], so you need to call get with Type :
  // example : get[Array[Double](myVariable)
  // return an Array[Double] only if it's possible for this Variable, else it return None
  def get[T](variable: Variable[A])(implicit m: Manifest[T]): Option[T] = {
    if (ClassUtils.assignable(variable.prototype.`type`.runtimeClass, m.runtimeClass)) {
      val casted = variable.prototype.`type`.runtimeClass.cast(variable.value)
      Some(casted.asInstanceOf[T])
    } else {
      None
    }

I hope these methods can help other people :)

You can see helping method ClassUtils.assignable here :

https://gist.github.com/4686167

and on the source forge project :

https://forge.iscpif.fr/projects/openmole/repository/revisions/master/entry/core/openmole/misc/org.openmole.misc.tools/src/main/scala/org/openmole/misc/tools/obj/ClassUtils.scala


Need Your Help

Dynamic Superfish menu problem with IE

javascript asp.net jquery menu

Iam using superfish menu. And using iframe for loading pages.

How are Shadow DOM events from under <content> targeted?

polymer web-component shadow-dom

I'm trying to understand what events that originate in light DOM look like when received in shadow DOM via a &lt;content&gt; element. I'm reading the Shadow DOM W3C Draft, and I don't entirely unde...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.