Take the 2-minute tour ×

In language like python and ruby to ask the language what index-related methods its string class supports (which methods’ names contain the word “index”) you can do

“”.methods.sort.grep /index/i

And in java

List results = new ArrayList();  
Method[] methods = String.class.getMethods();  
    Method m = methods[i];  
    if (m.getName().toLowerCase().indexOf(“index”) != -1) {  
String[] names = (String[]) results.toArray();  
return names;  

How would you do the same thing in Scala?

share|improve this question
Think i found it "wow".getClass.getMethods.toList.map(m => m.getName).sort((a, b) => (a compareTo b) < 0 ).filter( s => s.matches("index(.*)")) –  skyde May 22 '10 at 1:08
Out of curiosity, what are you going to do with those method names once you've got them? If it's so you know what you can type next in an interactive setting, the Scala REPL has good tab-completion. Check it out. –  Randall Schulz May 22 '10 at 1:41
Excellent tip, Randall! For some reason I just never thought to try... –  pdbartlett May 22 '10 at 2:10
The tab completion doesn't find methods from traits. For example, "1.m<tab>" suggests nothing, but "1.max(2)" works fine. –  Rich Jan 20 at 18:33

5 Answers 5

up vote 22 down vote accepted

Curious that no one tried a more direct translation:

.getClass.getMethods.map(_.getName) // methods
.sorted                             // sort
.filter(_ matches "(?i).*index.*")  // grep /index/i

So, some random thoughts.

  • The difference between "methods" and the hoops above is striking, but no one ever said reflection was Java's strength.

  • I'm hiding something about sorted above: it actually takes an implicit parameter of type Ordering. If I wanted to sort the methods themselves instead of their names, I'd have to provide it.

  • A grep is actually a combination of filter and matches. It's made a bit more complex because of Java's decision to match whole strings even when ^ and $ are not specified. I think it would some sense to have a grep method on Regex, which took Traversable as parameters, but...

So, here's what we could do about it:

implicit def toMethods(obj: AnyRef) = new { 
  def methods = obj.getClass.getMethods.map(_.getName)

implicit def toGrep[T <% Traversable[String]](coll: T) = new {
  def grep(pattern: String) = coll filter (pattern.r.findFirstIn(_) != None)
  def grep(pattern: String, flags: String) = {
    val regex = ("(?"+flags+")"+pattern).r
    coll filter (regex.findFirstIn(_) != None)

And now this is possible:

"".methods.sorted grep ("index", "i")
share|improve this answer
That's almost what the OP had except for the "sorted" Are yo using 2.8? –  OscarRyz May 22 '10 at 2:17
@Oscar Yes, that's 2.8. On Scala 2.7 there is sort, but not on all collections. –  Daniel C. Sobral May 22 '10 at 2:31
This isn't really the same -- in Ruby x.methods includes methods accessible via mixins, whereas x.getClass.getMethods does not in Scala. Try 1.methods in Ruby and then try 1.getClass.getMethods in Scala. –  Rich Jan 20 at 18:02

More or less the same way:

val names = classOf[String].getMethods.toSeq.
    filter(_.getName.toLowerCase().indexOf(“index”) != -1).
    sort(((e1, e2) => (e1 compareTo e2) < 0))

But all on one line.

To make it more readable,

val names = for(val method <- classOf[String].getMethods.toSeq
    if(method.getName.toLowerCase().indexOf("index") != -1))
    yield { method.getName }
val sorted = names.sort(((e1, e2) => (e1 compareTo e2) < 0))
share|improve this answer

Just using the Java code direct will get you most of the way there, as Scala classes are still JVM ones. You could port the code to Scala pretty easily as well, though, for fun/practice/ease of use in REPL.

share|improve this answer

This is as far as I got:

"".getClass.getMethods.map(_.getName).filter( _.indexOf("in")>=0)  

It's strange Scala array doesn't have sort method.


It would end up like.

share|improve this answer
Yes, but list does –  sblundy May 22 '10 at 1:19
classOf[String].getMethods.toList.map(_.getName).sort( _ < _ ).filter( _.matches("index(.*)")) This is what i got –  skyde May 22 '10 at 1:21
paste.pocoo.org/show/216854 –  missingfaktor May 22 '10 at 1:23
It says: warning: there were deprecation warnings; re-run with -deprecation for details and gives me an empty list –  OscarRyz May 22 '10 at 1:25
scala.Array are implicitly converted to scala.collection.mutable.WrappedArray which has the methods sortBy and sortWith. See the scaladocs: goo.gl/5pJD –  missingfaktor May 22 '10 at 1:25

Now, wait a minute.

I concede Java is verbose compared to Ruby for instance.

But that piece of code shouldn't have been so verbose in first place.

Here's the equivalent :

    Collection<String> mds = new TreeSet<String>();
    for( Method m : "".getClass().getMethods()) {
        if( m.getName().matches(".*index.*")){  mds.add( m.getName() ); }

Which has almost the same number of characters as the marked as correct, Scala version

share|improve this answer

Your Answer


