Find out if a scala class inherits from a specific trait

2,211 views
Skip to first unread message

Sébastien Druon

unread,
Mar 2, 2011, 10:52:33 AM3/2/11
to scala...@googlegroups.com
Hello!

How do I find out in my code if a scala class inherits from a specific trait?
ex:
val myClass = this.getClass
if myClass.hasTrait[MyTrait] // I am looking for such a method

Thanks in advance for the help

Sébastien

√iktor Klang

unread,
Mar 2, 2011, 11:05:16 AM3/2/11
to scala-user
On Wed, Mar 2, 2011 at 4:52 PM, Sébastien Druon <sdr...@spotuse.com> wrote:
Hello!

How do I find out in my code if a scala class inherits from a specific trait?
ex:
val myClass = this.getClass
if myClass.hasTrait[MyTrait] // I am looking for such a method

isAssignableFrom?
 

Thanks in advance for the help

Sébastien



--
Viktor Klang,
Code Connoisseur
Work:   Scalable Solutions
Code:   github.com/viktorklang
Follow: twitter.com/viktorklang
Read:   klangism.tumblr.com

Sébastien Druon

unread,
Mar 2, 2011, 11:23:29 AM3/2/11
to √iktor Klang, scala-user
Apparently it doe not work with traits (it is a Java method?)
error: not found: value MyTrait
[INFO]       println(klass.isAssignableFrom(MyTrait))

Thanks again for the help

Sebastien

√iktor Klang

unread,
Mar 2, 2011, 11:26:04 AM3/2/11
to Sébastien Druon, scala-user
classOf[MyTrait].isAssignableFrom(classOf[SomeClassPossiblyImplementingMyTrait])

Sébastien Druon

unread,
Mar 2, 2011, 11:42:35 AM3/2/11
to √iktor Klang, scala-user
Thanks this solved the problem!! ;-)

Kevin Wright

unread,
Mar 2, 2011, 11:53:37 AM3/2/11
to Sébastien Druon, √iktor Klang, scala-user
You can also use manifests:

    manifest[SomeClassPossiblyImplementingMyTrait] <:< manifest[MyTrait]

Though you'd probably get hold of your Manifest in the first place by doing something more like:

    def fn[T: Manifest](x: T) = {
      val isSubtype = manifest[T] <:< manifest[MyTrait]
      ...
    }


Or, if you want to check it statically, and refuse to compile unless you absolutely have a subtype relationship, then you can just try to look up that relationship as an implicit:

    implicitly[SomeClassPossiblyImplementingMyTrait <:< MyTrait]

Or make it part of a method signature:

    def fn[T <: MyTrait](x: T) = {
      ...
--
Kevin Wright

gtalk / msn : kev.lee...@gmail.com
mail: kevin....@scalatechnology.com
vibe / skype: kev.lee.wright
quora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Donald McLean

unread,
Mar 2, 2011, 11:59:50 AM3/2/11
to Sébastien Druon, scala...@googlegroups.com
Wouldn't using isInstance work?

classOf[MyTrait].isInstance(this)

--
Family photographs are a critical legacy for
ourselves and our descendants. Protect that
legacy with a digital backup and recovery plan.

For more information, follow my blog:

http://familyhistoricaltrust.blogspot.com/

Brian Schlining

unread,
Mar 2, 2011, 12:27:06 PM3/2/11
to scala...@googlegroups.com
trait Foo { val b = "I am Foo" }
class Bar { val a = "I am Bar" }
val c = new Bar() with Foo
c.isInstanceOf[Foo] // returns true
c.isInstanceOf[Bar] // returns true

--
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Brian Schlining
bschl...@gmail.com

Paul Phillips

unread,
Mar 2, 2011, 12:40:35 PM3/2/11
to Brian Schlining, scala...@googlegroups.com
On 3/2/11 6:27 PM, Brian Schlining wrote:
> trait Foo { val b = "I am Foo" }
> class Bar { val a = "I am Bar" }
> val c = new Bar() with Foo
> c.isInstanceOf[Foo] // returns true
> c.isInstanceOf[Bar] // returns true

But wait, there's more!

scala> trait Foo
defined trait Foo

scala> trait Bar
defined trait Bar

scala> class Bippy extends Foo with Bar { }
defined class Bippy

scala> def f(x: Any) = x match { case _: Foo with Bar => true ; case _
=> false }
f: (x: Any)Boolean

scala> f(new Foo { })
res0: Boolean = false

scala> f(new Bar { })
res1: Boolean = false

scala> f(new Bar with Foo { })
res2: Boolean = true

scala> f(new Foo with Bar { })
res3: Boolean = true

scala> f(new Bippy)
res4: Boolean = true

How is this feat achieved?

scala> class A { def f(x: Any) = x match { case _: Foo with Bar => true
; case _ => false } }
defined class A

scala> :javap -verbose A
Compiled from "<console>"
[...]
public boolean f(java.lang.Object);
Code:
Stack=1, Locals=3, Args_size=2
0: aload_1
1: astore_2
2: aload_2
// One! One instance check! A Ha Ha!
3: instanceof #8; //class Foo
6: ifeq 20
9: aload_2
// Two! Two instance checks! A Ha Ha!
10: instanceof #10; //class Bar
13: ifeq 20
16: iconst_1
17: goto 21
20: iconst_0
21: ireturn
LineNumberTable:
line 9: 0

Jason Zaugg

unread,
Mar 2, 2011, 1:08:36 PM3/2/11
to Paul Phillips, Brian Schlining, scala...@googlegroups.com
On Wed, Mar 2, 2011 at 6:40 PM, Paul Phillips <pa...@improving.org> wrote:

> But wait, there's more!

> scala> def f(x: Any) = x match { case _: Foo with Bar => true ; case _ =>
> false }
> f: (x: Any)Boolean

> How is this feat achieved?


>
> scala> class A { def f(x: Any) = x match { case _: Foo with Bar => true ;
> case _ => false } }
> defined class A
>
> scala> :javap -verbose A
> Compiled from "<console>"
> [...]
> public boolean f(java.lang.Object);
>  Code:
>   Stack=1, Locals=3, Args_size=2
>   0:   aload_1
>   1:   astore_2
>   2:   aload_2
>   // One! One instance check! A Ha Ha!
>   3:   instanceof      #8; //class Foo
>   6:   ifeq    20
>   9:   aload_2
>   // Two! Two instance checks! A Ha Ha!
>   10:  instanceof      #10; //class Bar

In a case of synchronicity, I happened across that feature scarcely
two hours ago. Somehow I had a good feeling that it was going to work.
Cop that, erasure.

-jason

Reply all
Reply to author
Forward
0 new messages