SlideShare una empresa de Scribd logo
1 de 41
Descargar para leer sin conexión
聚石@taobao.com
https://github.com/zhongl
Real-World Scala
Get Started
Create Project
$ g8 typesafehub/scala-sbt
Scala Project Using sbt
organization [org.example]: me.zhongl
name [Scala Project]: demo
scala_version [2.9.2]:
version [0.1-SNAPSHOT]:
Template applied in ./demo
$ tree demo
demo
├── README
├── project
│ └── DemoBuild.scala
└── src
└── main
└── scala
└── me
└── zhongl
└── Demo.scala
Project Structure
Build Spec
import sbt._
import sbt.Keys._
object DemoBuild extends Build {
lazy val demo = Project(
id = "demo",
base = file("."),
settings = Project.defaultSettings ++ Seq(
name := "demo",
organization := "me.zhongl",
version := "0.1-SNAPSHOT",
scalaVersion := "2.9.2"
// add other settings here
)
)
}
Hello, demo
$ sbt run
[info] Loading global plugins from ~/.sbt/plugins
[info] Loading project definition from ~/demo/project
[info] Set current project to demo (in build file:~demo/)
[info] Running me.zhongl.Demo
Hello, demo
[success] Total time: 0 s, completed 2013-5-24 9:38:47
IDE Plugins
$ cat ~/.sbt/plugins/build.sbt // Global
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" %
"1.2.0")
$ cat ~/demo/project/plugins.sbt // Project
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" %
"1.2.0")
$ sbt gen-idea // Create IDE Files
Dependencies
settings = Project.defaultSettings ++ Seq(
name := "demo",
organization := "me.zhongl",
version := "0.1-SNAPSHOT",
scalaVersion := "2.9.2",
libraryDependencies := Seq(
"org.scala-lang" % "scala-library" % "2.9.2",
"org.scalatest" %% "scalatest" % "1.7.2" % "test"
// "org.scalatest" % "scalatest_2.9.2" % "1.7.2" % "test"
)
)
Resolver
# ~/.sbt/local.sbt
resolvers <<= resolvers {rs =>
val localMaven = "Local Maven Repository" at "file://"
+Path.userHome.absolutePath+"/.m2/repository"
localMaven +: rs
}
Package
$ sbt package
$ sbt package-bin
$ sbt package-doc
$ sbt package-src
Publish
$ sbt publish // central repos
$ sbt publish-local // local repos
● giter8
● sbt
● sbt-idea
● sbteclipse
● nbsbt
● Typesafe Activator
● Scala Maven Plugin
● Buildr
● Gradle Scala Plugin
References
Behavior-Drive Development
package me.zhongl
import org.scalatest.FunSpec
import org.scalatest.matchers.ShouldMatchers
class DemoSpec extends FunSpec with ShouldMatchers {
describe("Demo") {
it("should sum two integers") {
Demo sum (1, 2) should be (3)
}
}
}
Demo Spec
Continue Test
$ sbt
> ~ test
[info] Compiling 1 Scala source to ~/demo/target/scala-
2.9.2/test-classes...
[error] ~/demo/src/test/scala/me/zhongl/DemoSpec.scala:9:
value sum is not a member of object me.zhongl.Demo
[error] Demo sum (1, 2) should be (3)
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
[error] Total time: 2 s, completed 2013-5-24 11:19:08
1. Waiting for source changes... (press enter to
interrupt)
Implement
package me.zhongl
object Demo extends App {
println("Hello, demo")
def sum(x: Int, y: Int) = x + y
}
[info] Compiling 1 Scala source to ~/demo/target/scala-
2.9.2/classes...
[info] DemoSpec:
[info] Demo
[info] - should sum two integers
[info] Passed: : Total 1, Failed 0, Errors 0, Passed 1,
Skipped 0
[success] Total time: 1 s, completed 2013-5-24 11:23:16
2. Waiting for source changes... (press enter to
interrupt)
Continue Test
Test Only
> test-only me.zhongl.DemoSpec
[info] DemoSpec:
[info] Demo
[info] - should sum two integers
[info] Passed: : Total 1, Failed 0, Errors 0, Passed 1,
Skipped 0
[success] Total time: 1 s, completed 2013-5-24 11:30:06
More Matchers
List(1, 2, 3) should have size (3)
"Scala" should startWith ("Sc")
Map("K" -> "V") should contain key ("K")
book should have ('title ("Programming in Scala"))
evaluating { assert(1 < 0) } should produce
[AssertionError]
● http://www.scalatest.org/ (备梯)
● http://etorreborre.github.io/specs2/
● https://code.google.com/p/scalacheck/
● http://scalamock.org/
References
Coverage
Scct plugin
# project/plugins.sbt
resolvers += Classpaths.typesafeResolver
resolvers += "scct-github-repository" at "http://mtkopone.
github.com/scct/maven-repo"
addSbtPlugin("reaktor" % "sbt-scct" % "0.2-SNAPSHOT")
# project/DemoBuild.scala
settings = Project.defaultSettings ++ Seq(
id := "demo"
...
) ++ ScctPlugin.instrumentSettings
Scct plugin
$ sbt clean scct:test
$ sbt
> ;clean ;scct:test
# open
./target/scala_2.9.2/coverage-report/index.html
Scct plugin
● http://mtkopone.github.io/scct/
References
Effective Scala
No statement
// Bad
def findPeopleIn(c: City, ps: Set[People]) = {
val found = new mutable.HashSet[People]
for (p <- ps) {
for(a <- p.addresses) {
if (a.city == c) found.put(p)
}
}
return found
}
Be expression
// Good
def findPeopleIn(c: City, ps: Set[People]) = {
for {
p <- ps
a <- p.addresses
if a.city = c
} yield p
}
Functional Magic
def firstPrimeGreatThan(num: Int): Int = {
def prime(s: Stream[Int],f: Int => Boolean): Int = s match
{
case h #:: t if f(h) => h
case h #:: t => prime(t filter (_ % h > 0), f)
}
prime(Stream from 2, _ > num)
}
assert(firstPrimeGreatThan(20) == 23)
assert(firstPrimeGreatThan(100) == 101)
Use require
class Person(val name: String, val age: Int) {
// Bad
if (name == null || age <= 0)
throw new IllegalArguemntException()
// Good
require(name != null, "name is required.")
require(age > 0, "age should greater than zero.")
}
DSL
class Matcher(s: String) {
def shouldMatch(regex: String) =
require(s != null && s.matches(regex),
"[" + s + "] should match " + regex)
}
implicit val str2Matcher = new Matcher(_:String)
class Person(val name: String, val age: Int) {
name shouldMatch """w+"""
}
Limit the scope of Implicits
● http://docs.scala-lang.org/
● http://twitter.github.io/effectivescala/
● http://twitter.github.io/scala_school/
● http://zh.scala-tour.com/
● http://stackoverflow.com/tags/scala/info
● https://github.com/languages/Scala
References
Books
● Scala for the Impatient (中文版)
● Programming Scala Tackle Multi-Core
Complexity on the Java Virtual Machine(中文
版)
● Scala in Depth (翻译中)
● Programming in Scala: A Comprehensive
Step-by-Step Guide, 2nd Edition
@odersky
@jboner
Typesafe
Akka
Slick
Play
@邓草原
@fujohnwang
@hongjiang_wang
China Scala User Group
Thanks

Más contenido relacionado

La actualidad más candente

Wprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache HadoopWprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache Hadoop
Sages
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 Devs
Jason Hanson
 

La actualidad más candente (20)

Tasks: you gotta know how to run them
Tasks: you gotta know how to run themTasks: you gotta know how to run them
Tasks: you gotta know how to run them
 
Flux and InfluxDB 2.0 by Paul Dix
Flux and InfluxDB 2.0 by Paul DixFlux and InfluxDB 2.0 by Paul Dix
Flux and InfluxDB 2.0 by Paul Dix
 
React native-firebase startup-mtup
React native-firebase startup-mtupReact native-firebase startup-mtup
React native-firebase startup-mtup
 
[Quase] Tudo que você precisa saber sobre tarefas assíncronas
[Quase] Tudo que você precisa saber sobre  tarefas assíncronas[Quase] Tudo que você precisa saber sobre  tarefas assíncronas
[Quase] Tudo que você precisa saber sobre tarefas assíncronas
 
Меняем javascript с помощью javascript
Меняем javascript с помощью javascriptМеняем javascript с помощью javascript
Меняем javascript с помощью javascript
 
Oop assignment 02
Oop assignment 02Oop assignment 02
Oop assignment 02
 
Wprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache HadoopWprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache Hadoop
 
Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & Collections
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
05 pig user defined functions (udfs)
05 pig user defined functions (udfs)05 pig user defined functions (udfs)
05 pig user defined functions (udfs)
 
Ordered Record Collection
Ordered Record CollectionOrdered Record Collection
Ordered Record Collection
 
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash courseCodepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
 
Flux and InfluxDB 2.0
Flux and InfluxDB 2.0Flux and InfluxDB 2.0
Flux and InfluxDB 2.0
 
Async Microservices with Twitter's Finagle
Async Microservices with Twitter's FinagleAsync Microservices with Twitter's Finagle
Async Microservices with Twitter's Finagle
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
OO JS for AS3 Devs
OO JS for AS3 DevsOO JS for AS3 Devs
OO JS for AS3 Devs
 
Mca 2nd sem u-4 operator overloading
Mca 2nd  sem u-4 operator overloadingMca 2nd  sem u-4 operator overloading
Mca 2nd sem u-4 operator overloading
 
Cambio de bases
Cambio de basesCambio de bases
Cambio de bases
 
Compositional I/O Stream in Scala
Compositional I/O Stream in ScalaCompositional I/O Stream in Scala
Compositional I/O Stream in Scala
 
Transducers in JavaScript
Transducers in JavaScriptTransducers in JavaScript
Transducers in JavaScript
 

Similar a Real world scala

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
Tino Isnich
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
David Padbury
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
ConFoo
 

Similar a Real world scala (20)

SCALA - Functional domain
SCALA -  Functional domainSCALA -  Functional domain
SCALA - Functional domain
 
GPars For Beginners
GPars For BeginnersGPars For Beginners
GPars For Beginners
 
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012Gradle build tool that rocks with DSL JavaOne India 4th May 2012
Gradle build tool that rocks with DSL JavaOne India 4th May 2012
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
ゼロから始めるScalaプロジェクト
ゼロから始めるScalaプロジェクトゼロから始めるScalaプロジェクト
ゼロから始めるScalaプロジェクト
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01Gradleintroduction 111010130329-phpapp01
Gradleintroduction 111010130329-phpapp01
 
Kotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projectsKotlin Developer Starter in Android projects
Kotlin Developer Starter in Android projects
 
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
Kotlin Developer Starter in Android - STX Next Lightning Talks - Feb 12, 2016
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Refactoring
RefactoringRefactoring
Refactoring
 
Practical Testing of Ruby Core
Practical Testing of Ruby CorePractical Testing of Ruby Core
Practical Testing of Ruby Core
 
Java patterns in Scala
Java patterns in ScalaJava patterns in Scala
Java patterns in Scala
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
Tres Gemas De Ruby
Tres Gemas De RubyTres Gemas De Ruby
Tres Gemas De Ruby
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
 

Más de lunfu zhong (7)

项目求生指南
项目求生指南项目求生指南
项目求生指南
 
Spring boot
Spring bootSpring boot
Spring boot
 
Lego: A brick system build by scala
Lego: A brick system build by scalaLego: A brick system build by scala
Lego: A brick system build by scala
 
Zhongl scala summary
Zhongl scala summaryZhongl scala summary
Zhongl scala summary
 
Housemd
HousemdHousemd
Housemd
 
Instroduce Hazelcast
Instroduce HazelcastInstroduce Hazelcast
Instroduce Hazelcast
 
Jvm分享20101228
Jvm分享20101228Jvm分享20101228
Jvm分享20101228
 

Último

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 

Real world scala

  • 1.
  • 5. Create Project $ g8 typesafehub/scala-sbt Scala Project Using sbt organization [org.example]: me.zhongl name [Scala Project]: demo scala_version [2.9.2]: version [0.1-SNAPSHOT]: Template applied in ./demo
  • 6. $ tree demo demo ├── README ├── project │ └── DemoBuild.scala └── src └── main └── scala └── me └── zhongl └── Demo.scala Project Structure
  • 7. Build Spec import sbt._ import sbt.Keys._ object DemoBuild extends Build { lazy val demo = Project( id = "demo", base = file("."), settings = Project.defaultSettings ++ Seq( name := "demo", organization := "me.zhongl", version := "0.1-SNAPSHOT", scalaVersion := "2.9.2" // add other settings here ) ) }
  • 8. Hello, demo $ sbt run [info] Loading global plugins from ~/.sbt/plugins [info] Loading project definition from ~/demo/project [info] Set current project to demo (in build file:~demo/) [info] Running me.zhongl.Demo Hello, demo [success] Total time: 0 s, completed 2013-5-24 9:38:47
  • 9. IDE Plugins $ cat ~/.sbt/plugins/build.sbt // Global addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0") $ cat ~/demo/project/plugins.sbt // Project addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.2.0") $ sbt gen-idea // Create IDE Files
  • 10. Dependencies settings = Project.defaultSettings ++ Seq( name := "demo", organization := "me.zhongl", version := "0.1-SNAPSHOT", scalaVersion := "2.9.2", libraryDependencies := Seq( "org.scala-lang" % "scala-library" % "2.9.2", "org.scalatest" %% "scalatest" % "1.7.2" % "test" // "org.scalatest" % "scalatest_2.9.2" % "1.7.2" % "test" ) )
  • 11. Resolver # ~/.sbt/local.sbt resolvers <<= resolvers {rs => val localMaven = "Local Maven Repository" at "file://" +Path.userHome.absolutePath+"/.m2/repository" localMaven +: rs }
  • 12. Package $ sbt package $ sbt package-bin $ sbt package-doc $ sbt package-src
  • 13. Publish $ sbt publish // central repos $ sbt publish-local // local repos
  • 14. ● giter8 ● sbt ● sbt-idea ● sbteclipse ● nbsbt ● Typesafe Activator ● Scala Maven Plugin ● Buildr ● Gradle Scala Plugin References
  • 16. package me.zhongl import org.scalatest.FunSpec import org.scalatest.matchers.ShouldMatchers class DemoSpec extends FunSpec with ShouldMatchers { describe("Demo") { it("should sum two integers") { Demo sum (1, 2) should be (3) } } } Demo Spec
  • 17. Continue Test $ sbt > ~ test [info] Compiling 1 Scala source to ~/demo/target/scala- 2.9.2/test-classes... [error] ~/demo/src/test/scala/me/zhongl/DemoSpec.scala:9: value sum is not a member of object me.zhongl.Demo [error] Demo sum (1, 2) should be (3) [error] ^ [error] one error found [error] (test:compile) Compilation failed [error] Total time: 2 s, completed 2013-5-24 11:19:08 1. Waiting for source changes... (press enter to interrupt)
  • 18. Implement package me.zhongl object Demo extends App { println("Hello, demo") def sum(x: Int, y: Int) = x + y }
  • 19. [info] Compiling 1 Scala source to ~/demo/target/scala- 2.9.2/classes... [info] DemoSpec: [info] Demo [info] - should sum two integers [info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0 [success] Total time: 1 s, completed 2013-5-24 11:23:16 2. Waiting for source changes... (press enter to interrupt) Continue Test
  • 20. Test Only > test-only me.zhongl.DemoSpec [info] DemoSpec: [info] Demo [info] - should sum two integers [info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0 [success] Total time: 1 s, completed 2013-5-24 11:30:06
  • 21. More Matchers List(1, 2, 3) should have size (3) "Scala" should startWith ("Sc") Map("K" -> "V") should contain key ("K") book should have ('title ("Programming in Scala")) evaluating { assert(1 < 0) } should produce [AssertionError]
  • 22. ● http://www.scalatest.org/ (备梯) ● http://etorreborre.github.io/specs2/ ● https://code.google.com/p/scalacheck/ ● http://scalamock.org/ References
  • 24. Scct plugin # project/plugins.sbt resolvers += Classpaths.typesafeResolver resolvers += "scct-github-repository" at "http://mtkopone. github.com/scct/maven-repo" addSbtPlugin("reaktor" % "sbt-scct" % "0.2-SNAPSHOT") # project/DemoBuild.scala settings = Project.defaultSettings ++ Seq( id := "demo" ... ) ++ ScctPlugin.instrumentSettings
  • 25. Scct plugin $ sbt clean scct:test $ sbt > ;clean ;scct:test # open ./target/scala_2.9.2/coverage-report/index.html
  • 29. No statement // Bad def findPeopleIn(c: City, ps: Set[People]) = { val found = new mutable.HashSet[People] for (p <- ps) { for(a <- p.addresses) { if (a.city == c) found.put(p) } } return found }
  • 30. Be expression // Good def findPeopleIn(c: City, ps: Set[People]) = { for { p <- ps a <- p.addresses if a.city = c } yield p }
  • 31. Functional Magic def firstPrimeGreatThan(num: Int): Int = { def prime(s: Stream[Int],f: Int => Boolean): Int = s match { case h #:: t if f(h) => h case h #:: t => prime(t filter (_ % h > 0), f) } prime(Stream from 2, _ > num) } assert(firstPrimeGreatThan(20) == 23) assert(firstPrimeGreatThan(100) == 101)
  • 32. Use require class Person(val name: String, val age: Int) { // Bad if (name == null || age <= 0) throw new IllegalArguemntException() // Good require(name != null, "name is required.") require(age > 0, "age should greater than zero.") }
  • 33. DSL class Matcher(s: String) { def shouldMatch(regex: String) = require(s != null && s.matches(regex), "[" + s + "] should match " + regex) } implicit val str2Matcher = new Matcher(_:String) class Person(val name: String, val age: Int) { name shouldMatch """w+""" }
  • 34. Limit the scope of Implicits
  • 35. ● http://docs.scala-lang.org/ ● http://twitter.github.io/effectivescala/ ● http://twitter.github.io/scala_school/ ● http://zh.scala-tour.com/ ● http://stackoverflow.com/tags/scala/info ● https://github.com/languages/Scala References
  • 36. Books ● Scala for the Impatient (中文版) ● Programming Scala Tackle Multi-Core Complexity on the Java Virtual Machine(中文 版) ● Scala in Depth (翻译中) ● Programming in Scala: A Comprehensive Step-by-Step Guide, 2nd Edition
  • 38.