Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping through each class in a package in Scala

Tags:

scala

Is there a way I can "loop through" the set of classes in a specified package in Scala?

The use case is managing a set of services inheriting from a BaseService trait that get exposed by a provided name to a REST API. A Manager class needs to be able to provide a list of services as well as validate that a provided service exists, and, if so, instantiate it an execute an overloaded function.

My thought is something like this pseudocode:

for ( clazz <- com.demo.pkg ) {
    val service = Class.forName(clazz).newInstance
    registerService( service )
}

Rather than instantiation, static methods on a same-named object to provide service name and description may be better.

In Python, this is trivial because of dir() and in PHP is fairly easy due to the classloader functions but I am new to Scala.

Also, I understand I may be approaching this incorrectly and would welcome feedback.

Update:

I have accepted JPP's answer below, but he's correct this is far too expensive a process for a routine operation. So I need to change my approach. The manager class will instead maintain a static list of service clases. While not ideal from a development perspective, the run-time speed gains seem well worth it.

like image 577
Josh David Miller Avatar asked Apr 13 '11 05:04

Josh David Miller


People also ask

How to use foreach in Scala?

Scala Map foreach() method with exampleThe foreach() method is utilized to apply the given function to all the elements of the map. Return Type: It returns all the elements of the map after applying the given function to each of them. So, the identical elements are taken only once.

How many ways we can use for loop in Scala?

We can also use multiple ranges in single for-loop. These ranges are separated by a semi-colon(;). Let us discuss with the help of an example. In the below example, we use two different ranges into a single loop, i.e, w <- 0 to 3; z<- 8 until 10.

Which expression is one way to iterate over a collection in Scala?

A simple for loop that iterates over a collection is translated to a foreach method call on the collection. A for loop with a guard (see Recipe 3.3) is translated to a sequence of a withFilter method call on the collection followed by a foreach call.

Which is a subclass of all classes in Scala?

Any has two direct subclasses: AnyVal. AnyRef.


1 Answers

Currently (2.8.1/2.9), Scala has no specific reflection/introspection system, but you're free to use Java's. In this particular case, you can port one of the techniques used on the Java side to list all classes in a package, e.g. as shown here (be sure to pick the version in the comments):

http://snippets.dzone.com/posts/show/4831

This technique actually doesn't use Java reflection to find about the classes; what it basically does instead is go through all resources available to the ClassLoader and check which ones are .class files.

I see a few caveats though:

  • As with Java, you can only see classes visible to a certain classloader (this may be a problem, e.g. in OSGi applications)
  • The operation is expensive enough in Java, and even more so in Scala, as scalac generates a lot of additional classes for all the anonymous functions generated in your code, which can be a significant number owing to methods like filter, map, flatMap, etc. You may try to filter them out based on their name.
like image 164
Jean-Philippe Pellet Avatar answered Oct 05 '22 13:10

Jean-Philippe Pellet