Question

While working my way through Cay S. Horstmann's "Scala for the Impatient", I noticed something interesting revealed by the first exercise in the first chapter.

  1. In the Scala REPL, type 3. followed by the Tab key. What methods can be applied?

When I do this, I get the following

scala> 3.
%              &              *              +              -              /              
>              >=             >>             >>>            ^              asInstanceOf   
isInstanceOf   toByte         toChar         toDouble       toFloat        toInt          
toLong         toShort        toString       unary_+        unary_-        unary_~        
|       

But I noticed that if I hit Tab a second time, I get a slightly different list.

scala> 3.
!=             ##             %              &              *              +              
-              /                            >=             >>             >>>            ^              asInstanceOf   
equals         getClass       hashCode       isInstanceOf   toByte         toChar         
toDouble       toFloat        toInt          toLong         toShort        toString       
unary_+        unary_-        unary_~        |    

What is the REPL trying to tell me here? Is there something special about the different methods that appear the second time?

Was it helpful?

Solution

Hitting tab twice in the REPL raises the verbosity of the completion:

If "methodName" is among z's completions, and verbosity > 0 indicating tab has been pressed twice consecutively, then we call alternativesFor and show a list of overloaded method signatures.

The following methods from the interpreter source indicate what's filtered for method completion when verbosity == 0 (i.e., when you've only hit tab once and aren't getting the alternativesFor version):

def anyRefMethodsToShow = Set("isInstanceOf", "asInstanceOf", "toString")

def excludeEndsWith: List[String] = Nil

def excludeStartsWith: List[String] = List("<") // <byname>, <repeated>, etc.

def excludeNames: List[String] =
  (anyref.methodNames filterNot anyRefMethodsToShow) :+ "_root_"

def exclude(name: String): Boolean = (
  (name contains "$") ||
  (excludeNames contains name) ||
  (excludeEndsWith exists (name endsWith _)) ||
  (excludeStartsWith exists (name startsWith _))
)

So with one tab you're getting the methods filtered by some rules that the interpreter developers have decided are reasonable and useful. Two tabs gives you the unfiltered version.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top