niedziela, 12 kwietnia 2015

W głąb Value Classes,Warsztaty ze ScalaCheck,Scalar

Temat pojawił się na warsztatach : Czy jeśli klasa rozszerza AnyVal i się wywali w Runtimime to co dokładnie będzie widać w stacktrace? Czy będzie informacja o tym, ze to była klasa czy też będzie tam widniał typ prymitywny?

Odpowiedź na tak postawione pytanie brzmi "Tak, masz rację, teraz mnie zostaw w spokoju"

Labolatorium

Na początek przygotujmy aparaturę badawczą

class Domenowa(val s:String) extends AnyVal
Ćwiczenie pierwsze - zrobić aby coś się wywaliło. Wrzućmy granat w środek :
val d=new Domenowa(null)
"Exception in thread "main" java.lang.NullPointerException
 at com.wlodar.nauka.oop.Domenowa$.hashCode$extension"
Zaraz zajrzymy pod mikroskop ale najpierw jeszcze jedna wypierdółka :
class Domenowa(val s:String) extends AnyVal{
    null.toString
  }

I tu się tego nie spodziewałem :
Error:(18, 10) this statement is not allowed in value class
    null.toString
         ^
Wygląda na to, ze ValueClasses w ogóle nie mogą mieć konstruktorów.
To jeszcze inaczej :
class Domenowa(val s:String) extends AnyVal{
    def logic=null.toString
}
I się wywaliło :
Exception in thread "main" java.lang.NullPointerException
 at com.wlodar.nauka.oop.Domenowa$.logic$extension

Pod oscyloskop go

Po kompilacji mamy tka naprawdę dwie klasy. Ta Domenowa$ nie pojawia się gdy nie rozszerzamy AnyVal
-rw-rw-r-- 1 pawel pawel 1875 kwi 12 21:22 Domenowa.class
-rw-rw-r-- 1 pawel pawel 1170 kwi 12 21:22 Domenowa$.class

javap Domenowa

public final class com.wlodar.nauka.oop.Domenowa {
  public static boolean equals$extension(java.lang.String, java.lang.Object);
  public static int hashCode$extension(java.lang.String);
  public static java.lang.String logic$extension(java.lang.String);
  public java.lang.String s();
  public java.lang.String logic();
  public int hashCode();
  public boolean equals(java.lang.Object);
  public com.wlodar.nauka.oop.Domenowa(java.lang.String);
}

javap Domenowa$

public final class com.wlodar.nauka.oop.Domenowa$ {
  public static final com.wlodar.nauka.oop.Domenowa$ MODULE$;
  public static {};
  public final java.lang.String logic$extension(java.lang.String);
  public final int hashCode$extension(java.lang.String);
  public final boolean equals$extension(java.lang.String, java.lang.Object);
}

Strzelam, że kiedy wywoływana jest metoda logic na klasie Domenowej to gdzieś tam pod spodem ten string ze środka jest przekazywany do tego logic$extension(java.lang.String). Jest jedna instancja Domenowa$, ValueClasses nie maja pól to nei ma stanu i to wszystko tak działa (chyba). Postanowiłem zdekompilowac kod z opcja -c by zobaczyć bytecoda
 public final java.lang.String logic$extension(java.lang.String);
    Code:
       0: aconst_null
       1: invokevirtual #18                 // Method java/lang/Object.toString:()Ljava/lang/String;
       4: areturn

Po czym się zastanowiłem po co właściwie chce go zobaczyć jak i tak się na tym nie znam?

To może jednak prościej

Potwórzmy kilka identycznych klas.
class Domenowa(val s:String) extends AnyVal{
    def logic=this.toString()
  }

println(new Domenowa("abc"))
    println(new Domenowa("abc"))
    println(new Domenowa("abc"))
    println(new Domenowa("abc"))
    println(new Domenowa("abc2"))
    println(new Domenowa("abc2"))
    println(new Domenowa("abc").logic)
    println(new Domenowa("abc").logic)
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@2d9410
com.wlodar.nauka.oop.Domenowa@2d9410
com.wlodar.nauka.oop.Domenowa@17862
com.wlodar.nauka.oop.Domenowa@17862
I cuda. Jak jest ten sam string to i jest ta sama referencja. Jeśli dla eksperymentu usuniemy extends AnyVal to już to nie działa. Czyli tu nie działa przez co udowadniamy , że ogólnie mechanizm jak taki działa.
class Domenowa(val s:String){
    def logic=this.toString()
  }

com.wlodar.nauka.oop.Domenowa@48140564
com.wlodar.nauka.oop.Domenowa@58ceff1
com.wlodar.nauka.oop.Domenowa@7c30a502
com.wlodar.nauka.oop.Domenowa@49e4cb85
com.wlodar.nauka.oop.Domenowa@2133c8f8
com.wlodar.nauka.oop.Domenowa@43a25848
com.wlodar.nauka.oop.Domenowa@3ac3fd8b
com.wlodar.nauka.oop.Domenowa@5594a1b5
wracamy do class Domenowa(val s:String) extends AnyVal{ def logic=this.toString() } Znowu zdekompiluje bytecod Domenowa$ (sam nie wiem po co).
 public final java.lang.String logic$extension(java.lang.String);
    Code:
       0: new           #16                 // class com/wlodar/nauka/oop/Domenowa
       3: dup
       4: aload_1
       5: invokespecial #19                 // Method com/wlodar/nauka/oop/Domenowa."":(Ljava/lang/String;)V
       8: invokevirtual #23                 // Method java/lang/Object.toString:()Ljava/lang/String;
      11: areturn

i niby tutaj jest instrukcja new, która tworzy klasę domenową. Według dokumentacji to alokuje nową instancję a jednak sprawdzaliśmy, że tak się nie dzieje. Co umacnia mnie w przekonaniu, ze na bytecodzie Javy się nie znam.
http://docs.scala-lang.org/overviews/core/value-classes.html

Najbliższe spotkania i warsztaty ze Scalacheck

W Maju/Czerwcu przyjedzie Damian Warszawski z Touka z warsztatem o Javie8 :
"
żeby się nie zastanawiać za długo to moja propozycja warsztatu: 

Intro to java8 workshop: 
agenda: 
Lambda Expressions 
Stream API 
DateTime package 

W ciągu tygodnia przygotuje repo na githubie i przygotuje krótki opis warsztatu.
"

I jeszcze jakoś na początku maja Cezary Draus który też pracuje w Touku (oraz pociągu relacji Łódź-Warszawa) zrobi warsztaty z intellij.

W tym wszystkim jedyny rozsądny termin w jaki mogę się wcisnąć z warsztatami to 20 kwietnia : Scalacheck i Property Based Testing - Warsztaty

Będą trzy iventy w tygodniu ale damy radę.

Scalar

W końcu laptop wygląda jak laptop do programowania :
Muszę sobie załatwić drugi zestaw na komputer w pracy zanim mi ktoś nie przylepi naklejek : "Sharepoint,Excel,Outlook,Ms Project,UML "
Konferencja była fajna i dłuższej relacji pisać nie będę bo ludzie później nie kumają dowcipów i rzucają kamieniami w okna :D Było fajnie i tyle.