Skip to content

Instantly share code, notes, and snippets.

@gkojax
Last active December 30, 2015 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gkojax/7782764 to your computer and use it in GitHub Desktop.
Save gkojax/7782764 to your computer and use it in GitHub Desktop.

この投稿はScala Advent Calendar 2013の4日目の記事です。

最近Scala勉強会 in 東京 #rpscalaで初心者向けセッションのコーナーが始めたみたいです。それに便乗して自分も初心者向けの記事というかscala習い始めにすごいなと思ったREPLの機能を何個か書いてみたいと思います。

結果を自動で変数に代入

scala> val a = 1 + 2
a: Int = 3

と変数aに入力したものを

scala> println(a)
3

として使えるのは当然ですが、単に

scala> 1 + 2
res1: Int = 3

と式だけ書いた場合はresXという変数に代入されます。

scala> println(res1)
3

Xの部分は、res1、res2、res3とインクリメントされていきます。

pasteモード

REPLというと1行ずつ入力していくようなイメージがあるかと思いますが、まとめて入力することも出来ます。

まずREPL上で「:paste」と打ってみて下さい。pasteモードに入ります。

scala> :paste
// Entering paste mode (ctrl-D to finish)

ここで複数行に渡る式を書いて

(1 to 10).toList.foreach {
  println _
}

ctrl-Dを押す。すると、複数行で書いたものがまとめてコンパイルされます。

この書き方だとコンパニオンオブジェクトも使えたはず。

どこかに書いたソースコードをコピペしてREPLに貼る、なんてときによく使えます。

ところで

2.11でREPLのコマンドいろいろ追加されそうなのに今気づいた。

StringとStringOpt

REPLの話題からそれますが。

REPLでもタブ補完があります。例えばString.でタブを押すとStringクラスのメソッド名の一覧がでます。

scala> "ABC". [TAB]
+                     asInstanceOf          charAt                codePointAt           codePointBefore       
codePointCount        compareTo             compareToIgnoreCase   concat                contains              
contentEquals         endsWith              equalsIgnoreCase      getBytes              getChars              
indexOf               intern                isEmpty               isInstanceOf          lastIndexOf           
length                matches               offsetByCodePoints    regionMatches         replace               
replaceAll            replaceFirst          split                 startsWith            subSequence           
substring             toCharArray           toLowerCase           toString              toUpperCase           
trim   

ところがこの一覧に存在しないメソッドが使えたりします。

scala> "ABC".min
res16: Char = A

Stringクラスに存在しないメソッドを呼んでるのにコンパイルエラーにならない。

何故なんでしょうねー。

ってところで裏で働いてるのが「暗黙の型変換(implicit conversions)」です。

具体的にはPredefの中のこいつ。StringからStringOptへの暗黙の型変換です。

"ABC"はStringクラスのインスタンスなのでminなんてメソッドが使えないのですが、あらかじめ暗黙の型変換が宣言されていれば、"ABC"をStringOptへ変換してからメソッドを呼ぶことができます。minはStringOptクラスのメソッドです。

REPLでStringOptのメソッドを確認。

scala> new scala.collection.immutable.StringOps("ABC")
res17: scala.collection.immutable.StringOps = ABC

scala> res17.
*                     ++                    ++:                   +:                    /:                    
/:\                   :+                    :\                    >                     >=                    
addString             aggregate             apply                 asInstanceOf          canEqual              
capitalize            collect               collectFirst          combinations          compare               
compareTo             contains              containsSlice         copyToArray           copyToBuffer          
corresponds           count                 diff                  distinct              drop                  
dropRight             dropWhile             endsWith              exists                filter                
filterNot             find                  flatMap               fold                  foldLeft              
foldRight             forall                foreach               format                formatLocal           
groupBy               grouped               hasDefiniteSize       head                  headOption            
indexOf               indexOfSlice          indexWhere            indices               init                  
inits                 intersect             isDefinedAt           isEmpty               isInstanceOf          
isTraversableAgain    iterator              last                  lastIndexOf           lastIndexOfSlice      
lastIndexWhere        lastOption            length                lengthCompare         lines                 
linesIterator         linesWithSeparators   map                   max                   maxBy                 
min                   minBy                 mkString              nonEmpty              padTo                 
par                   partition             patch                 permutations          prefixLength          
product               r                     reduce                reduceLeft            reduceLeftOption      
reduceOption          reduceRight           reduceRightOption     replaceAllLiterally   repr                  
reverse               reverseIterator       reverseMap            sameElements          scan                  
scanLeft              scanRight             segmentLength         seq                   size                  
slice                 sliding               sortBy                sortWith              sorted                
span                  split                 splitAt               startsWith            stringPrefix          
stripLineEnd          stripMargin           stripPrefix           stripSuffix           sum                   
tail                  tails                 take                  takeRight             takeWhile             
to                    toArray               toBoolean             toBuffer              toByte                
toDouble              toFloat               toIndexedSeq          toInt                 toIterable            
toIterator            toList                toLong                toMap                 toSeq                 
toSet                 toShort               toStream              toString              toTraversable         
toVector              union                 updated               view                  withFilter            
zip                   zipAll                zipWithIndex    

それにしても知らないメソッド結構多いなー。

sbtとかplayのconsole

sbtやplayを使ってる人は「sbt console」とか「play console」て打つとREPLが立ち上がります。普通のREPLとの違いは、そのsbtやplayのプロジェクト内で作ったクラスをREPLから呼び出すことができます。自分で作ったクラスの動作をREPL上から確認したいというときに便利。

終わりに

最近、Scala勉強会 in 東京 #rpscalaで初心者向けセッションのコーナーが始まったみたいで初心者の方が参加しやすいタイミングとなっています(最初と最後に2回書いた)。

@xuwei-k
Copy link

xuwei-k commented Dec 4, 2013

String からの暗黙変換は、もうひとつあります https://github.com/scala/scala/blob/v2.10.3/src/library/scala/LowPriorityImplicits.scala#L86

@gkojax
Copy link
Author

gkojax commented Dec 5, 2013

WrappedStringは知らなかったです。
後で追記しておきます。
ツッコミありがとうございます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment