groovy & grails - lecture 5
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

groovy & grails - lecture 5

  • 472 views
Uploaded on

Eclipse & linux tips ...

Eclipse & linux tips
Debugging with Eclipse
A thought on code design
Object methods : a few step forwards
Inheritance

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
472
On Slideshare
472
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
9
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • horizontal learning\n
  • you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
  • you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
  • you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
  • you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
  • read the function shortcuts and try to memorize your most commons\nmaybe my shortcut are mac oriented\n
  • read the function shortcuts and try to memorize your most commons\nmaybe my shortcut are mac oriented\n
  • 8% of the remaining is spent inbugging\n
  • 8% of the remaining is spent inbugging\n
  • 8% of the remaining is spent inbugging\n
  • it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
  • it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
  • it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
  • it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
  • \n
  • \n
  • use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
  • use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
  • use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
  • use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
  • use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
  • use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
  • writing the code is often not a one-off process\n
  • writing the code is often not a one-off process\n
  • writing the code is often not a one-off process\n
  • writing the code is often not a one-off process\n
  • writing the code is often not a one-off process\n
  • \n
  • a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
  • a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
  • a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
  • a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
  • a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
  • \n
  • \n
  • setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
  • setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
  • setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
  • setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
  • setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
  • \n
  • \n
  • Example: Integer.MAX_VALUE\n
  • Example: Integer.MAX_VALUE\n
  • Example: Integer.MAX_VALUE\n
  • much simpler than java\n
  • much simpler than java\n
  • much simpler than java\n
  • much simpler than java\n
  • method < 10 statements\n
  • method < 10 statements\n
  • method < 10 statements\n
  • method < 10 statements\n
  • method < 10 statements\n
  • \n
  • \n
  • \n
  • but writing setter in that manner is very common\n
  • but writing setter in that manner is very common\n
  • but writing setter in that manner is very common\n
  • but writing setter in that manner is very common\n
  • several thousand of additional and mass def lookup for each protein mass...\n
  • several thousand of additional and mass def lookup for each protein mass...\n
  • several thousand of additional and mass def lookup for each protein mass...\n
  • several thousand of additional and mass def lookup for each protein mass...\n
  • if without curly bracket => execute only the next statement\n
  • if without curly bracket => execute only the next statement\n
  • if without curly bracket => execute only the next statement\n
  • \n
  • \n
  • Go to lecture 4 practicals for more example\n
  • Go to lecture 4 practicals for more example\n
  • Go to lecture 4 practicals for more example\n
  • Go to lecture 4 practicals for more example\n
  • Go to lecture 4 practicals for more example\n
  • Go to lecture 4 practicals for more example\n
  • Go to lecture 4 practicals for more example\n
  • we do not take into account here the check on enz class.\n
  • we do not take into account here the check on enz class.\n
  • we do not take into account here the check on enz class.\n
  • interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
  • interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
  • interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
  • interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
  • interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
  • This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
  • This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
  • This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
  • \n
  • \n
  • we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
  • we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
  • we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
  • we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
  • we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
  • if AminoAcidSequence has no meaning to exist by itself (maybe), it could be declared Abstract\n
  • if AminoAcidSequence has no meaning to exist by itself (maybe), it could be declared Abstract\n
  • we do not talk about visibility\ntoString() exist from the Object class point of view, which is an ancestor of AminoAcid\n
  • we do not talk about visibility\ntoString() exist from the Object class point of view, which is an ancestor of AminoAcid\n
  • we do not talk about visibility\ntoString() exist from the Object class point of view, which is an ancestor of AminoAcid\n

Transcript

  • 1. Groovy: Efficiency Oriented ProgrammingLecture 5Master Proteomics & Bioinformatics - University of GenevaAlexandre Masselot - summer 2011
  • 2. Contents‣ Eclipse & linux tips‣ Debugging with Eclipse‣ A thought on code design‣ Object methods : a few step forwards‣ Inheritance
  • 3. A couple of linux (shell) tips‣ Print all files named peaklist-*.mgf residing under a given directory:find /home/alex/tmp -name “peaklist-*.mgf”
  • 4. A couple of linux (shell) tips‣ Print all files named peaklist-*.mgf residing under a given directory: find /home/alex/tmp -name “peaklist-*.mgf”‣ Get “ls -l” like details by appending -ls option
  • 5. A couple of linux (shell) tips‣ Print all files named peaklist-*.mgf residing under a given directory: find /home/alex/tmp -name “peaklist-*.mgf”‣ Get “ls -l” like details by appending -ls option‣ You want to download a fasta file, based on a list of accession codes acList="P41159 Q9Y5Q6 Q70Z44" for ac in $acList; do echo "downloading $ac" ; wget --quiet -O $ac.fasta http://uniprot.org/uniprot/$ac.fasta; done
  • 6. A couple of linux (shell) tips‣ Print all files named peaklist-*.mgf residing under a given directory: find /home/alex/tmp -name “peaklist-*.mgf”‣ Get “ls -l” like details by appending -ls option‣ You want to download a fasta file, based on a list of accession codes acList="P41159 Q9Y5Q6 Q70Z44" for ac in $acList; do echo "downloading $ac" ; wget --quiet -O $ac.fasta http://uniprot.org/uniprot/$ac.fasta; done‣ The same, in multi-line version: for ac in $acList do echo "downloading $ac" wget --quiet -O $ac.fasta http://uniprot.org/uniprot/$ac.fasta done
  • 7. A couple of eclipse tips‣ launches the last executed program (or test) - <ctrl>-<shift>-F11 - configure through preferences > run/debug > launching > launch operation - possible to run a whole directory as junit test
  • 8. A couple of eclipse tips‣ launches the last executed program (or test) - <ctrl>-<shift>-F11 - configure through preferences > run/debug > launching > launch operation - possible to run a whole directory as junit test‣ It is possible to hide/show the current method / editor block - little +/- sign in the margin to toggle show/hide - shortcut <numpad> /
  • 9. Eclipse: debugging‣ 90% of a developers time is spent debugging his code
  • 10. Eclipse: debugging‣ 90% of a developers time is spent debugging his code‣ Old fashion way: add println statement - enhance println of object defined by you through defining a String toString() method - damned tedious: define println details, comment in/out, pollutes the code
  • 11. Eclipse: debugging‣ 90% of a developers time is spent debugging his code‣ Old fashion way: add println statement - enhance println of object defined by you through defining a String toString() method - damned tedious: define println details, comment in/out, pollutes the code‣ Configurable logger (log4j) - print on console, but with different level of details (debug/info/warn/error) - cleaner in code - no need to comment in/out - we will see this functionality later
  • 12. Eclipse: debugging (cont’d)‣ Debugging consists in three major aspects:
  • 13. Eclipse: debugging (cont’d)‣ Debugging consists in three major aspects:‣ Breakpoints - a breakpoint is a “flag” positioned at a given line in the source code - at execution time, the program will halt when reaching the break point - possible to move on step by step (into, over or return) or to next breakpoint
  • 14. Eclipse: debugging (cont’d)‣ Debugging consists in three major aspects:‣ Breakpoints - a breakpoint is a “flag” positioned at a given line in the source code - at execution time, the program will halt when reaching the break point - possible to move on step by step (into, over or return) or to next breakpoint‣ Displaying objects - when the program is halted, objects available in the current scope can be analyzed - it is possible to dig in the object fields
  • 15. Eclipse: debugging (cont’d)‣ Debugging consists in three major aspects:‣ Breakpoints - a breakpoint is a “flag” positioned at a given line in the source code - at execution time, the program will halt when reaching the break point - possible to move on step by step (into, over or return) or to next breakpoint‣ Displaying objects - when the program is halted, objects available in the current scope can be analyzed - it is possible to dig in the object fields‣ Call stack - The stack of method calls at the current position
  • 16. Eclipse: debugging (cont’d)‣ Launching in debug mode - instead of “run as...”, call “debug as...” - <ctrl>-F11
  • 17. Eclipse: debugging (cont’d)‣ Launching in debug mode - instead of “run as...”, call “debug as...” - <ctrl>-F11‣ Eclipse open the debug perspective, with different windows for - variables - breakpoint list - call stack - current code - menu for stepping or resuming execution
  • 18. 8
  • 19. debug mode 8
  • 20. execution control debug mode 8
  • 21. execution control debug mode call stack 8
  • 22. execution control debug mode call stack break point 8
  • 23. execution control debug mode call stack current code line break point 8
  • 24. execution control debug mode call stack variable current code line break point 8
  • 25. A thought on code design‣ Writing a script with all in one to answer a (lab) question is only code writing
  • 26. A thought on code design‣ Writing a script with all in one to answer a (lab) question is only code writing‣ Architecting a problem into a piece of software is also a matter of breaking the problem - into classes achieving independent functionalities (test, change a sub part) - offer the possibility to re-use functionalities
  • 27. A thought on code design‣ Writing a script with all in one to answer a (lab) question is only code writing‣ Architecting a problem into a piece of software is also a matter of breaking the problem - into classes achieving independent functionalities (test, change a sub part) - offer the possibility to re-use functionalities‣ But do not over-architect a software at start; prefer to make it evolve constantly (think agile)
  • 28. A thought on code design‣ Writing a script with all in one to answer a (lab) question is only code writing‣ Architecting a problem into a piece of software is also a matter of breaking the problem - into classes achieving independent functionalities (test, change a sub part) - offer the possibility to re-use functionalities‣ But do not over-architect a software at start; prefer to make it evolve constantly (think agile)‣ For example, the practicals Protein class should not contain the download/readFromFasta (what will happen when reading from xml?)
  • 29. A thought on code design‣ Writing a script with all in one to answer a (lab) question is only code writing‣ Architecting a problem into a piece of software is also a matter of breaking the problem - into classes achieving independent functionalities (test, change a sub part) - offer the possibility to re-use functionalities‣ But do not over-architect a software at start; prefer to make it evolve constantly (think agile)‣ For example, the practicals Protein class should not contain the download/readFromFasta (what will happen when reading from xml?)‣ Your motto : “I want to understand my own code in 6 months”
  • 30. OOP: more depth
  • 31. OOP: more depth‣ Several aspects of OOP - creating a new class - fields - static fields - constructors - methods - unit testing - overriding operators - method or closures? - inheritance
  • 32. OOP: Making a new class‣ By convention, class name starts with an upper case (when variable usually start with lower case)
  • 33. OOP: Making a new class‣ By convention, class name starts with an upper case (when variable usually start with lower case)‣ Within a source directory, create a package (a subdirectory structure, where ‘.’ is a directory path separator), for example unige.mpb.lec5.example
  • 34. OOP: Making a new class‣ By convention, class name starts with an upper case (when variable usually start with lower case)‣ Within a source directory, create a package (a subdirectory structure, where ‘.’ is a directory path separator), for example unige.mpb.lec5.example‣ In eclipse File -> new -> package (<ctrl>-N package)
  • 35. OOP: Making a new class‣ By convention, class name starts with an upper case (when variable usually start with lower case)‣ Within a source directory, create a package (a subdirectory structure, where ‘.’ is a directory path separator), for example unige.mpb.lec5.example‣ In eclipse File -> new -> package (<ctrl>-N package)‣ Within this package, create a class : File -> new -> groovy class and set name Person.
  • 36. OOP: Making a new class‣ By convention, class name starts with an upper case (when variable usually start with lower case)‣ Within a source directory, create a package (a subdirectory structure, where ‘.’ is a directory path separator), for example unige.mpb.lec5.example‣ In eclipse File -> new -> package (<ctrl>-N package)‣ Within this package, create a class : File -> new -> groovy class and set name Person.‣ A Person.groovy file is create with package unige.mpb.lec5.examples class Person{ ... }
  • 37. OOP: making a new class (cont’d)
  • 38. OOP: making a new class (cont’d)class Person{ String name // field of type String Date birth // field of type Date int age(){ // a method returning an int return (new Date()).year - birth.year }}
  • 39. one field : one property link to one instance 13
  • 40. Class: fields‣ Fields are properties of a class, they can be dynamically or statically typed (of any existing type (Integer, List, Map, etc...)
  • 41. Class: fields‣ Fields are properties of a class, they can be dynamically or statically typed (of any existing type (Integer, List, Map, etc...)‣ Field are by default associated to an instance of the class (an object generated by new Person())
  • 42. Class: fields‣ Fields are properties of a class, they can be dynamically or statically typed (of any existing type (Integer, List, Map, etc...)‣ Field are by default associated to an instance of the class (an object generated by new Person())‣ They can be changed directly from outside the class (GBean) guy.name = ‘Jimmy‘ guy.setName(‘Jimmy’)
  • 43. Class: fields‣ Fields are properties of a class, they can be dynamically or statically typed (of any existing type (Integer, List, Map, etc...)‣ Field are by default associated to an instance of the class (an object generated by new Person())‣ They can be changed directly from outside the class (GBean) guy.name = ‘Jimmy‘ guy.setName(‘Jimmy’)‣ Or read println guy.name println guy.getName()
  • 44. Class: fields‣ Fields are properties of a class, they can be dynamically or statically typed (of any existing type (Integer, List, Map, etc...)‣ Field are by default associated to an instance of the class (an object generated by new Person())‣ They can be changed directly from outside the class (GBean) guy.name = ‘Jimmy‘ guy.setName(‘Jimmy’)‣ Or read println guy.name println guy.getName()‣ Inside a method, the instance properties are directly used by their name int age(){return (new Date()).year - birth.year}
  • 45. one static field: one property linked to the class 15
  • 46. one static field : the same for all instances 16
  • 47. Class: static fields‣ Fields can also be static i.e. a global value, shared by all instances of the class (by convention upper case).
  • 48. Class: static fields‣ Fields can also be static i.e. a global value, shared by all instances of the class (by convention upper case).‣ If we come back to our previous Person example, we want static int AGE_LIMIT = 18 boolean canDrive(){return age() >= AGE_LIMIT}
  • 49. Class: static fields‣ Fields can also be static i.e. a global value, shared by all instances of the class (by convention upper case).‣ If we come back to our previous Person example, we want static int AGE_LIMIT = 18 boolean canDrive(){return age() >= AGE_LIMIT}‣ We can change this value at once for all Person instances Person.AGE_LIMIT = 16
  • 50. Constructor‣ Thanks to the scripting spirit, there is no need to declare constructor (the function to instantiate an object)
  • 51. Constructor‣ Thanks to the scripting spirit, there is no need to declare constructor (the function to instantiate an object)‣ Field can be filled with a map structure Person girl=new Person(name:‘Marylyn’)
  • 52. Constructor‣ Thanks to the scripting spirit, there is no need to declare constructor (the function to instantiate an object)‣ Field can be filled with a map structure Person girl=new Person(name:‘Marylyn’)‣ It is not compulsory to set all the field
  • 53. Constructor‣ Thanks to the scripting spirit, there is no need to declare constructor (the function to instantiate an object)‣ Field can be filled with a map structure Person girl=new Person(name:‘Marylyn’)‣ It is not compulsory to set all the field‣ To set default value to a field, you can define it in the property declaration String name=‘John Doe’
  • 54. Methods
  • 55. Methods‣ Methods are functions, with are called within the context of an object instance
  • 56. Methods‣ Methods are functions, with are called within the context of an object instance‣ All properties of the instance are accessed directly
  • 57. Methods‣ Methods are functions, with are called within the context of an object instance‣ All properties of the instance are accessed directly‣ It is possible to modify the instance, directly addressing the instance fields
  • 58. Methods‣ Methods are functions, with are called within the context of an object instance‣ All properties of the instance are accessed directly‣ It is possible to modify the instance, directly addressing the instance fields‣ It is possible to pass argument to the function
  • 59. Methods‣ Methods are functions, with are called within the context of an object instance‣ All properties of the instance are accessed directly‣ It is possible to modify the instance, directly addressing the instance fields‣ It is possible to pass argument to the function‣ It is possible to return a value (of whatever type)
  • 60. OOP : methods‣ A method is a function called in the context of an object instance
  • 61. OOP : methods‣ A method is a function called in the context of an object instance‣ All fields of the object can be addressed directly from within a method
  • 62. OOP : methods‣ A method is a function called in the context of an object instance‣ All fields of the object can be addressed directly from within a method‣ Methods are functions: lecture 2 about function apply: - dynamic/static types for arguments - arguments can be named - arguments can have default values - if multiple functions are defined with the same name but different list/ type of arguments, the call context will choose the correct one
  • 63. Methods: setter and getter‣ Protein field can be accessed in two equivalent manner prot.sequence prot.getSequence()
  • 64. Methods: setter and getter‣ Protein field can be accessed in two equivalent manner prot.sequence prot.getSequence()‣ Or set via two manners prot.sequence=‘ACDEFG’ prot.setSequence(‘ACDEFG’)
  • 65. Methods: setter and getter‣ Protein field can be accessed in two equivalent manner prot.sequence prot.getSequence()‣ Or set via two manners prot.sequence=‘ACDEFG’ prot.setSequence(‘ACDEFG’)‣ In fact reading or setting the field via the field calls the getter/setter implicitly (methods are generated automatically by the groovy compiler)
  • 66. Methods: setter and getter‣ Protein field can be accessed in two equivalent manner prot.sequence prot.getSequence()‣ Or set via two manners prot.sequence=‘ACDEFG’ prot.setSequence(‘ACDEFG’)‣ In fact reading or setting the field via the field calls the getter/setter implicitly (methods are generated automatically by the groovy compiler)‣ By default, a setSequence method is defined void setSequence(sequence){ //void means no value returned this.sequence=sequence //this is the current object // we could have name the argument with ‘seq’ }
  • 67. Methods: setter and getter (cont’d)‣ Imagine we want to get the protein mass, computed from the sequence def mp = prot.mass
  • 68. Methods: setter and getter (cont’d)‣ Imagine we want to get the protein mass, computed from the sequence def mp = prot.mass‣ Their is no explicit mass field, but a static MassCalculator is attached to class Protein static MassCalculator MASS_CALCULATOR
  • 69. Methods: setter and getter (cont’d)‣ Imagine we want to get the protein mass, computed from the sequence def mp = prot.mass‣ Their is no explicit mass field, but a static MassCalculator is attached to class Protein static MassCalculator MASS_CALCULATOR‣ We can define a getMass method double getMass(){ return MASS_CALCULATOR.sequenceMass(this) }
  • 70. Methods: setter and getter (cont’d)‣ Imagine we want to get the protein mass, computed from the sequence def mp = prot.mass‣ Their is no explicit mass field, but a static MassCalculator is attached to class Protein static MassCalculator MASS_CALCULATOR‣ We can define a getMass method double getMass(){ return MASS_CALCULATOR.sequenceMass(this) }‣ Problem with the current solution: we recompute mass at each time we call it (think of sorting a long list of protein on their mass)
  • 71. Methods: setter and getter (cont’d)‣ We could therefore have a mass field to Protein and set it with the correct value the first time we ask for it double mass = 0 ... double getMass(){ if(!mass) mass = MASS_CALCULATOR.sequenceMass(this) return mass }
  • 72. Methods: setter and getter (cont’d)‣ We could therefore have a mass field to Protein and set it with the correct value the first time we ask for it double mass = 0 ... double getMass(){ if(!mass) mass = MASS_CALCULATOR.sequenceMass(this) return mass }‣ We consider the mass field as a cached value
  • 73. Methods: setter and getter (cont’d)‣ We could therefore have a mass field to Protein and set it with the correct value the first time we ask for it double mass = 0 ... double getMass(){ if(!mass) mass = MASS_CALCULATOR.sequenceMass(this) return mass }‣ We consider the mass field as a cached value‣ Problem: what happen if we change the protein sequence?
  • 74. Methods: setter and getter (cont’d)‣ Solution : reset mass when we set the sequence def setSequence(sequence){ this.sequence=sequence mass=0 }
  • 75. Methods: setter and getter (cont’d)‣ Solution : reset mass when we set the sequence def setSequence(sequence){ this.sequence=sequence mass=0 }‣ If we need (e.g. at testing time) to access directly to the field, without going through the getMass() method, we still can my_prot.@mass
  • 76. Unit testing‣ Each method of a class must be tested, to ensure it fulfills the intended goals
  • 77. Unit testing‣ Each method of a class must be tested, to ensure it fulfills the intended goals‣ One class file = one test file - in another directory (src/test) - same package name - MyClass.groovy => MyClassTest.groovy
  • 78. Unit testing‣ Each method of a class must be tested, to ensure it fulfills the intended goals‣ One class file = one test file - in another directory (src/test) - same package name - MyClass.groovy => MyClassTest.groovy‣ Eclipse/groovy offers a integrated environment for that purpose
  • 79. Unit testing (cont’d)‣ In another source folder (typically src/tests/groovy), test will be generated: - select a class - File -> new -> Groovy Test Case - select the other src/test/groovy source folder - select junit 3 (better for later use of grails for the moment) - next -> select methods to be tested
  • 80. Unit testing (cont’d)‣ In another source folder (typically src/tests/groovy), test will be generated: - select a class - File -> new -> Groovy Test Case - select the other src/test/groovy source folder - select junit 3 (better for later use of grails for the moment) - next -> select methods to be tested‣ In junit 3, any method with name starting with test* will be used as test
  • 81. Unit testing (cont’d)‣ In another source folder (typically src/tests/groovy), test will be generated: - select a class - File -> new -> Groovy Test Case - select the other src/test/groovy source folder - select junit 3 (better for later use of grails for the moment) - next -> select methods to be tested‣ In junit 3, any method with name starting with test* will be used as test‣ right button -> run as -> junit test (<ctrl>-<alt>-X-T)
  • 82. Unit testing (cont’d)‣ In another source folder (typically src/tests/groovy), test will be generated: - select a class - File -> new -> Groovy Test Case - select the other src/test/groovy source folder - select junit 3 (better for later use of grails for the moment) - next -> select methods to be tested‣ In junit 3, any method with name starting with test* will be used as test‣ right button -> run as -> junit test (<ctrl>-<alt>-X-T)‣ Customize show view (<ctrl>-<alt>-Q-U + down arrow and tab)
  • 83. Methods: overriding operators‣ In lecture 1 (or “Groovy in Action”, chap. 3.3) we saw several operator (+, *, /) and how those operators are tight to a method name
  • 84. Methods: overriding operators‣ In lecture 1 (or “Groovy in Action”, chap. 3.3) we saw several operator (+, *, /) and how those operators are tight to a method name‣ For example, we like to write the cleavage of a Protein by an Enzyme List peptides=my_prot/trypsin //in Protein.groovy def div(enz){ return enz.cleav(this) //this is the current object }
  • 85. Methods: overriding operators‣ In lecture 1 (or “Groovy in Action”, chap. 3.3) we saw several operator (+, *, /) and how those operators are tight to a method name‣ For example, we like to write the cleavage of a Protein by an Enzyme List peptides=my_prot/trypsin //in Protein.groovy def div(enz){ return enz.cleav(this) //this is the current object }‣ Do not abuse of overriding operator (think that you want to understand your code in 6 months)
  • 86. Override spaceship: making objects comparable‣ A very common need is to make relevant the operators <, <=, ==, > and >=
  • 87. Override spaceship: making objects comparable‣ A very common need is to make relevant the operators <, <=, ==, > and >=‣ It is equivalent to override the spaceship operator <=>
  • 88. Override spaceship: making objects comparable‣ A very common need is to make relevant the operators <, <=, ==, > and >=‣ It is equivalent to override the spaceship operator <=>‣ First step: make your class implements the Comparable interface class MyClass implements Comparable{ ... }
  • 89. Override spaceship: making objects comparable‣ A very common need is to make relevant the operators <, <=, ==, > and >=‣ It is equivalent to override the spaceship operator <=>‣ First step: make your class implements the Comparable interface class MyClass implements Comparable{ ... }‣ Second step: code the logic of the spaceship (< return negative, == returns 0, and > returns positive integer) def int compareTo(other){ ... }
  • 90. Override spaceship: making objects comparable‣ A very common need is to make relevant the operators <, <=, ==, > and >=‣ It is equivalent to override the spaceship operator <=>‣ First step: make your class implements the Comparable interface class MyClass implements Comparable{ ... }‣ Second step: code the logic of the spaceship (< return negative, == returns 0, and > returns positive integer) def int compareTo(other){ ... }‣ See practicals for an example on Protein
  • 91. Method or closure?‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object in that you can pass a reference to it around just as you can a reference to any other object” (Groovy in Action - 5.1 A gentle introduction to closures)
  • 92. Method or closure?‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object in that you can pass a reference to it around just as you can a reference to any other object” (Groovy in Action - 5.1 A gentle introduction to closures)‣ From the caller point of view, method or closure at very similar
  • 93. Method or closure?‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object in that you can pass a reference to it around just as you can a reference to any other object” (Groovy in Action - 5.1 A gentle introduction to closures)‣ From the caller point of view, method or closure at very similar‣ However, we can modify a closure, thus modify the behavior of an action on an object, from outside the class
  • 94. Method or closure?‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object in that you can pass a reference to it around just as you can a reference to any other object” (Groovy in Action - 5.1 A gentle introduction to closures)‣ From the caller point of view, method or closure at very similar‣ However, we can modify a closure, thus modify the behavior of an action on an object, from outside the class‣ From the coding point of view, you can add closure in your class def myAction = { arg1, arg2 -> ... }
  • 95. Method or closure?‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object in that you can pass a reference to it around just as you can a reference to any other object” (Groovy in Action - 5.1 A gentle introduction to closures)‣ From the caller point of view, method or closure at very similar‣ However, we can modify a closure, thus modify the behavior of an action on an object, from outside the class‣ From the coding point of view, you can add closure in your class def myAction = { arg1, arg2 -> ... }‣ Then call it myObj.myAction(12, ‘abc’)
  • 96. Method or closure? (cont’d)‣ In Protein.groovy, consider the static method that turn ac into a url static def UNIPROT_AC_URL(ac){ return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL() }
  • 97. Method or closure? (cont’d)‣ In Protein.groovy, consider the static method that turn ac into a url static def UNIPROT_AC_URL(ac){ return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL() }‣ Problem : “I have no network (and that’s ok for testing purpose for example) and I want to modify the behavior without modifying Protein class itself. I have downloaded a list of fasta files in a local directory”
  • 98. Method or closure? (cont’d)‣ In Protein.groovy, consider the static method that turn ac into a url static def UNIPROT_AC_URL(ac){ return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL() }‣ Problem : “I have no network (and that’s ok for testing purpose for example) and I want to modify the behavior without modifying Protein class itself. I have downloaded a list of fasta files in a local directory”‣ A) turn the method into a closure static def UNIPROT_AC_URL={ac -> return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()}
  • 99. Method or closure? (cont’d)‣ In Protein.groovy, consider the static method that turn ac into a url static def UNIPROT_AC_URL(ac){ return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL() }‣ Problem : “I have no network (and that’s ok for testing purpose for example) and I want to modify the behavior without modifying Protein class itself. I have downloaded a list of fasta files in a local directory”‣ A) turn the method into a closure static def UNIPROT_AC_URL={ac -> return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()}‣ B) modify it (in ProteinTest.groovy setup() for example) Protein.UNIPROT_AC_URL = {ac -> return (new File("src/practicals/data/fastas/${ac}.fasta")).toURL }
  • 100. OOP: inheritance
  • 101. OOP: inheritance‣ In the practicals from lecture 4, an Enzyme cleaves a Protein and produces a List<String>
  • 102. OOP: inheritance‣ In the practicals from lecture 4, an Enzyme cleaves a Protein and produces a List<String>‣ Let’s consider it should produces a List<Peptide> where Peptide consists in - field String sequence - field Protein parentProtein - field int startPosition - method int getLength() - method double getMass() (with the same caching as for the Protein)
  • 103. Inheritance (cont’d)‣ Solution A: create a file Peptide.groovy strongly copied from Protein.groovy
  • 104. Inheritance (cont’d)‣ Solution A: create a file Peptide.groovy strongly copied from Protein.groovy‣ Problems: - lot of code is duplicated, thus bugs and test - not easy to read - modifying a functionality (think of getMass() caching) should be done
  • 105. Inheritance (cont’d)‣ Solution A: create a file Peptide.groovy strongly copied from Protein.groovy‣ Problems: - lot of code is duplicated, thus bugs and test - not easy to read - modifying a functionality (think of getMass() caching) should be done Protein Peptide accessionCode sequence sequence parentProtein downloadFasta(ac) startPosition getLength() toString() getMass() getLength() compareTo(o) toString() getMass() compareTo(o)
  • 106. Inheritance (cont’d)‣ Solution A: create a file Peptide.groovy strongly copied from Protein.groovy‣ Problems: - lot of code is duplicated, thus bugs and test - not easy to read - modifying a functionality (think of getMass() caching) should be done Protein common part Peptide accessionCode sequence parentProtein downloadFasta(ac) getLength() startPosition toString() getMass() toString() compareTo(o) compareTo(o)
  • 107. Inheritance (cont’d)
  • 108. Inheritance (cont’d)‣ Instead of having two classes, we can have a third one class AminoAcidSequence implements Comparable{ String sequence int getLength(){...} double getMass(){...} int compareTo(o){...} }
  • 109. Inheritance (cont’d)‣ Instead of having two classes, we can have a third one class AminoAcidSequence implements Comparable{ String sequence int getLength(){...} double getMass(){...} int compareTo(o){...} }‣ Then create Protein & Peptide classes that will inherit from AminoAcidSequence + add their own field & methods class Peptide extends AminoAcidSequence{ Protein parentProtein int startPosition String toString(){...} }
  • 110. Inheritance (cont’d)
  • 111. Inheritance (cont’d)‣ All the methods of the parent class are visible by the a derived class instance Peptide pept ... double m = pept.mass println pept.startPosition
  • 112. Inheritance (cont’d)‣ All the methods of the parent class are visible by the a derived class instance Peptide pept ... double m = pept.mass println pept.startPosition‣ If a method is redefined by a derived class, it takes the precedence (e.g. toString())
  • 113. Inheritance (cont’d)‣ All the methods of the parent class are visible by the a derived class instance Peptide pept ... double m = pept.mass println pept.startPosition‣ If a method is redefined by a derived class, it takes the precedence (e.g. toString())‣ We can access to the ancestor class method: e.g. compareTo(o), from the Protein point of view, takes into account the accessionCode, which to do not exist at AminoAcidSequence Level: def int compareTo(o){ return super.compareTo(o)?: (accessionCode <=> o.accessionCode)