Scala Practicein  patric.fornasier@thoughtworks.com    marc.hofer@thoughtworks.com
2&/82..9+8$&+&"0+&/;0+2-3+0<10-*0+#7+7=&"0=2>#50+2-3+;#(0?+                                                  ience        ...
Offices     2
a r n in g   Wpresentation Contains   code examples
A bit ofContext    about the project
Why Scala
What isScala
Object        Functional Oriented             Sc ala      ScriptableStatically Typed           JVM-                 based
Scala   Compile   Byte Code   JVM
Benefits
unc tio nal “F          n g”      ram miP rog
List<String> features = Arrays.asList("noFeature", "featureC",                                      "featureB", "featureA"...
List<String> javaFeatures = Arrays.asList("noFeature", "featureC",                                          "featureB", "f...
val currentFeatures = List("noFeature", "featureC", "featureB", "featureA")Result: "featureA_toggle, featureB_toggle"curre...
String result = "";List<String> currentFeatures = Arrays.asList("noFeature", "featureC",	 	 	 	                           ...
“L  ess   ilerpla te ”Bo
public class Property {}
class Property {}
public class Property {    private final String key;    private final String value;    private final String defaultValue; ...
class Property(key: String, value: String, default: String) {}
public class Property {    // ...    public String getKey() {      return key;    }    public String getValue() {      ret...
class Property(val key: String, val value: String, val default: String) {}
public class Property {    // ...    public Property changeTo(String newValue) {      return new Property(key, value, newV...
class Property(val key: String, val value: String, val default: String) {    def changeTo(newValue: String) = new Property...
public class Property {    // ...    @Override    public boolean equals(Object obj) {      if (!(obj instanceof Property))...
case class Property(key: String, value: String, default: String) {    def changeTo(newValue: String) = Property(key, newVa...
public class Property {     private final String key;     private final String value;     private final String defaultValu...
case class Property(key: String, value: String, default: String) {  def changeTo(newValue: String) = Property(key, newValu...
public class Property {                                                             case class Property(key: String, value...
“L  ess     ilerpla te ”  BoAnother Example:   { Blocks }
int statusCode = httpSupport.get("http://foo.com", new Block<Integer>() {  public Integer execute(HttpResponse response) {...
“J ava    p at ibi lity”Com
java -cp "lib/*" com.springer.core.app.Casper                  Scala library goes in here!
val java = new java.util.ArrayList[String]val scala: Seq[String] = foo filter { ... }
val log = Logger.getLogger("com.foo")log.debug("Hello!")
Libraryre-use                       JVM              “ Ge n tle                     gC  urv e”          L e arn in        ...
Su ppo rt/><XM L-
val pdfInfo = <PdfInfo hasAccess="false">                 <DDSId>12345</DDSId>                 <ContentType>Article</Conte...
val pdfInfoList = <PdfInfoList>	   	   	   	   	   	     <PdfInfo hasAccess="false">	   	   	   	   	      	    <DDSId>123...
“D  SL-Fri e nd ly”
Levels of Testing                                         SystemFunctional                    Unit                        ...
Unit Test DSLclass PropertyTest extends Spec with ShouldMatchers {    it("should render key and value separated with an eq...
Functional Test DSLclass ForgottenPasswordPageTests      extends FunctionalTestSpec with ForgottenPasswordSteps with Uris ...
Document Validation DSLtrait DDSValidationRules extends JournalXPaths with APlusPlusElements {    val journalRules = List(...
“Ac tiv e   mm un  ity”Co
“F un”
“F un”
“F un”val foo = (7 to 21)
“F un”List<Integers> foo = new ArrayList<Integers>()for (int i = 7; i <= 21; i++) {  foo.add(i);}
“F un”def eat(food: String = "plankton")
“F un”public void eat(String food) {...}public void eat() {  eat("plankton");}
“F un”get("http://foo.com") { statusCode }
“F un”httpSupport.get("http://foo.com", new Block<Integer>() {  public Integer execute(HttpResponse response) {    return ...
Drawbacks
“T oolSu ppo rt”
!?
1:10
re rop e ...”“ Mo
Scala Collection Librarydef ++ [B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]):That
Traits Galore in our codebase...    class JournalPageTests extends Spec with FunctionalTestSpec                           ...
xsbt
scalaz
Can→Should
RiskMitigations
Would wedo it again
l a im erd isc    use scala at your own risk
Thanks for    Listening   @patforna | @mhoefi
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Scala in practice
Upcoming SlideShare
Loading in …5
×

Scala in practice

379
-1

Published on

Manchester Geek Night 8 Feb 2012, Scala Experience - Pat Fornasier, Marc Hofer

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
379
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Scala in practice

  1. 1. Scala Practicein patric.fornasier@thoughtworks.com marc.hofer@thoughtworks.com
  2. 2. 2&/82..9+8$&+&"0+&/;0+2-3+0<10-*0+#7+7=&"0=2>#50+2-3+;#(0?+ ience Exper ign Optimising IT Des Organ isations Co nsulting Build & Release Man agement technology Testing
  3. 3. Offices 2
  4. 4. a r n in g Wpresentation Contains code examples
  5. 5. A bit ofContext about the project
  6. 6. Why Scala
  7. 7. What isScala
  8. 8. Object Functional Oriented Sc ala ScriptableStatically Typed JVM- based
  9. 9. Scala Compile Byte Code JVM
  10. 10. Benefits
  11. 11. unc tio nal “F n g” ram miP rog
  12. 12. List<String> features = Arrays.asList("noFeature", "featureC", "featureB", "featureA");for (String feature : features) { System.out.println(feature);}
  13. 13. List<String> javaFeatures = Arrays.asList("noFeature", "featureC", "featureB", "featureA");for (String feature : javaFeatures) { System.out.println(feature);} val scalaFeatures = List( "noFeature", "featureC", "featureB", "featureA") scalaFeatures foreach { println _ }
  14. 14. val currentFeatures = List("noFeature", "featureC", "featureB", "featureA")Result: "featureA_toggle, featureB_toggle"currentFeatures.filter { _.startsWith("feature") } .sorted .take(2) .map { _ + "_toggle" } .mkString(", ")
  15. 15. String result = "";List<String> currentFeatures = Arrays.asList("noFeature", "featureC", "featureB", "featureA");Collections.sort(currentFeatures);int i = 0, j = 0, take = 2; while(i < take && j < currentFeatures.size()) { String feature = currentFeatures.get(j++); if(feature.startsWith("feature")) { result += feature + "_toggle" + ((i++ != take) ? ", " : ""); }} currentFeatures.filter { _.startsWith("feature") } .sorted .take(2) .map { _ + "_toggle" } .mkString(", ")
  16. 16. “L ess ilerpla te ”Bo
  17. 17. public class Property {}
  18. 18. class Property {}
  19. 19. public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; }}
  20. 20. class Property(key: String, value: String, default: String) {}
  21. 21. public class Property { // ... public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; }}
  22. 22. class Property(val key: String, val value: String, val default: String) {}
  23. 23. public class Property { // ... public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); } @Override public String toString() { return String.format("%s=%s", key, value); }}
  24. 24. class Property(val key: String, val value: String, val default: String) { def changeTo(newValue: String) = new Property(key, newValue, default) def reset = new Property(key, default) override def toString = "%s=%s" format(key, value)}
  25. 25. public class Property { // ... @Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; }}
  26. 26. case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) override def toString = "%s=%s" format(key, value)}
  27. 27. public class Property { private final String key; private final String value; private final String defaultValue; public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; } public String getKey() { return key; } public String getValue() { return value; } public String getDefaultValue() { return defaultValue; } public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); } @Override public String toString() { return String.format("%s=%s", key, value); } @Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; }}
  28. 28. case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) def reset = Property(key, default) override def toString = "%s=%s" format(key, value)}
  29. 29. public class Property { case class Property(key: String, value: String, default: String) { def changeTo(newValue: String) = Property(key, newValue, default) private final String key; def reset = Property(key, default) private final String value; override def toString = "%s=%s" format(key, value) private final String defaultValue; } public Property(String key, String value, String defaultValue) { this.key = key; this.value = value; this.defaultValue = defaultValue; } vs 5 public String getKey() { return key; 45 } public String getValue() { return value; } L OCs public String getDefaultValue() { return defaultValue; } public Property changeTo(String newValue) { return new Property(key, value, newValue); } public Property reset() { return new Property(key, value); } @Override public boolean equals(Object obj) { if (!(obj instanceof Property)) return false; Property other = (Property) obj; return other.key.equals(key) && other.value.equals(value) && other.defaultValue.equals(defaultValue) } @Override public int hashCode() { int result = 17; result = 31 * result + key; result = 31 * result + value; result = 31 * result + defaultValue; return result; } @Override public String toString() { return String.format("%s=%s", key, value); }} * ignoring blank lines
  30. 30. “L ess ilerpla te ” BoAnother Example: { Blocks }
  31. 31. int statusCode = httpSupport.get("http://foo.com", new Block<Integer>() { public Integer execute(HttpResponse response) { return response.getStatusLine().getStatusCode()); }});String content = httpSupport.get("http://foo.com", new Block<String>() { public Integer execute(HttpResponse response) { return EntityUtils.toString(response.getEntity()); }});httpSupport.get("http://foo.com", new VoidBlock() { public void execute(HttpResponse response) {}}); val statusCode = get("http://foo.com") { statusCode } val content = get("http://foo.com") { toString } get("http://foo.com")
  32. 32. “J ava p at ibi lity”Com
  33. 33. java -cp "lib/*" com.springer.core.app.Casper Scala library goes in here!
  34. 34. val java = new java.util.ArrayList[String]val scala: Seq[String] = foo filter { ... }
  35. 35. val log = Logger.getLogger("com.foo")log.debug("Hello!")
  36. 36. Libraryre-use JVM “ Ge n tle gC urv e” L e arn in “Java without ;”
  37. 37. Su ppo rt/><XM L-
  38. 38. val pdfInfo = <PdfInfo hasAccess="false"> <DDSId>12345</DDSId> <ContentType>Article</ContentType> </PdfInfo> val contentType = (pdfInfo "ContentType").textval hasAccess = (pdfInfo "@hasAccess").text.toBoolean
  39. 39. val pdfInfoList = <PdfInfoList> <PdfInfo hasAccess="false"> <DDSId>12345</DDSId> <ContentType>Article</ContentType> </PdfInfo> <PdfInfo hasAccess="true"> <DDSId>54321</DDSId> <ContentType>Book</ContentType> </PdfInfo> </PdfInfoList>case class PdfInfo(xml: NodeSeq) { val ddsId = (xml "DDSId").head.text val hasAccess = (xml "@hasAccess").head.text val contentType = (xml "ContentType").head.text}(pdfInfoList "PdfInfo") map { PdfInfo(_) }
  40. 40. “D SL-Fri e nd ly”
  41. 41. Levels of Testing SystemFunctional Unit App2 App1 Integration DB App3
  42. 42. Unit Test DSLclass PropertyTest extends Spec with ShouldMatchers { it("should render key and value separated with an equals sign") { Property("shark", "fish").toString should equal ("shark=fish") }}
  43. 43. Functional Test DSLclass ForgottenPasswordPageTests extends FunctionalTestSpec with ForgottenPasswordSteps with Uris { it("should validate user email") { given(iNavigateTo(ForgottenPasswordPage)) when(iSubmitEmail("invalid@email.com")) then(iShouldSeeInvalidEmailErrorMessage) }}
  44. 44. Document Validation DSLtrait DDSValidationRules extends JournalXPaths with APlusPlusElements { val journalRules = List( No(JournalTitle) is Invalid, MoreThanOneElementIn(JournalArticle) is Invalid, BadLanguageIn(JournalArticleLanguage) is Invalid, JournalIssue With No(JournalIssueCoverYear) is Invalid, Bibliography With No(BibliographyHeading) is Invalid, MarkupIn(JournalTitle) is Unsupported, MarkupIn(JournalAuthor) is Unsupported )}
  45. 45. “Ac tiv e mm un ity”Co
  46. 46. “F un”
  47. 47. “F un”
  48. 48. “F un”val foo = (7 to 21)
  49. 49. “F un”List<Integers> foo = new ArrayList<Integers>()for (int i = 7; i <= 21; i++) { foo.add(i);}
  50. 50. “F un”def eat(food: String = "plankton")
  51. 51. “F un”public void eat(String food) {...}public void eat() { eat("plankton");}
  52. 52. “F un”get("http://foo.com") { statusCode }
  53. 53. “F un”httpSupport.get("http://foo.com", new Block<Integer>() { public Integer execute(HttpResponse response) { return response.getStatusLine().getStatusCode()); }});
  54. 54. Drawbacks
  55. 55. “T oolSu ppo rt”
  56. 56. !?
  57. 57. 1:10
  58. 58. re rop e ...”“ Mo
  59. 59. Scala Collection Librarydef ++ [B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]):That
  60. 60. Traits Galore in our codebase... class JournalPageTests extends Spec with FunctionalTestSpec with JournalPageSteps with SearchResultsPageSteps with LanguageSteps with LanguageSupport with JavascriptSupport with Uris with IssuePageSteps with VolumesAndIssuesPageSteps with CoverImageUrlBuilders with FakeEntitlementSteps with FullTextPageSteps with CommonAbstractSteps with GoogleAnalyticsSteps with ActionSectionSteps { ... }
  61. 61. xsbt
  62. 62. scalaz
  63. 63. Can→Should
  64. 64. RiskMitigations
  65. 65. Would wedo it again
  66. 66. l a im erd isc use scala at your own risk
  67. 67. Thanks for Listening @patforna | @mhoefi

×