Methods Why methods?  A method gives a name to something that you want to do, so you don’t have to think about.

Download Report

Transcript Methods Why methods?  A method gives a name to something that you want to do, so you don’t have to think about.

Methods
Why methods?

A method gives a name to something that you want to do, so you
don’t have to think about how to do it, you just do it





The name should be descriptive and memorable
Since a method is an action, it’s name is usually a verb
Methods that do more than one thing are harder to name and harder to use
Typical names: toChar, sort, sqrt, startsWith
Example usages:

scala> ('a' + 1).toChar
res4: Char = b
scala> "anteater".startsWith("ant")
res7: Boolean = true
2
Two kinds of methods

Classes describe objects (more about this later!)



When we ask an object to compute something for us, we use dot
notation




String is a class, and "anteater" is an object of that class
Int is a class, and 'a' + 1 is an object of that class
('a' + 1).toChar
"anteater".startsWith("ant")
We’ll learn more about classes later, but for now we will study
“standalone” methods
You have already met a couple of these methods


val name = readLine("What is your name?" )
println("Hello, " + name)
3
Method syntax

Here is the syntax for a method definition:
def methodName(parameters): returnType = expression

The parameters are a list of name: type pairs




Scala can usually figure out the types of values for itself
scala> val v = 3.6
v: Double = 3.6
Scala cannot determine parameter types, so you must specify them explicity
Scala can usually determine the returnType, but sometimes you have to specify it
Here is the syntax for a method call (or invocation):
methodName(arguments)



The arguments (sometimes called actual parameters) may be any expressions
You do not specify the types of arguments, they just have to have the types
expected by the method
You can use a method anywhere a value of that type is required
4
Example: Palindromes


A palindrome is a word or phrase that reads the same way backwards and
forwards, for example, radar
String objects have a reverse method, so we can define an isPalindrome
method as follows:


and use it like this:


scala> isPalindrome("radar")
res16: Boolean = true
We had to specify the type of the parameter s


scala> def isPalindrome(s: String) = s == s.reverse
isPalindrome: (s: String)Boolean
We always have to specify the type of each parameter
We didn’t have to specify the return type (but we can if we want to)

def isPalindrome(s: String): String = s == s.reverse

Scala can usually figure out the return type
5
Palindromes II

There is nothing wrong with writing very short methods (such as
isPalindrome) if it makes your program easier to understand



So let’s add some complexity!
“Anna” is normally considered to be a palindrome, regardless of capitalization


In this case, I think just writing s == s.reverse is just as easy
scala> isPalindrome("Anna")
res18: Boolean = false
Strings have a method toLowerCase to replace capital letters with their
lowercase equivalents


scala> def isPalindrome(s: String) =
| s.toLowerCase == s.reverse.toLowerCase
isPalindrome: (s: String)Boolean
scala> isPalindrome("Anna")
res20: Boolean = true
Note: The vertical bar, |, is Scala’s prompt to tell us our expression isn’t finished
6
A little bit of string manipulation

We can use a for loop to step through the characters of a string
one at a time


We can use the + operator to add characters to a string


scala> for (ch <- "Anna") {
| println(ch)
| }
A
n
n
a
scala> "abc" + 'd'
res23: String = abcd
We’ll use these in our next definition of isPalindrome
7
Removing non-letters from a string

scala> var result = "" // empty string
result: String = ""
scala> var message = "One if by land, two if by sea"
message: String = One if by land, two if by sea
scala>
|
|
|
|
for (ch <- message) {
if (ch.isLetter) {
result = result + ch
}
}
scala> result
res25: String = Oneifbylandtwoifbysea
8
Palindromes III

scala> :paste
// Entering paste mode (ctrl-D to finish)
def isPalindrome(s: String) = {
var string1 = ""
for (ch <- s) {
if (ch.isLetter) {
string1 = string1 + ch
}
}
string1.toLowerCase == string1.reverse.toLowerCase
}
// Exiting paste mode, now interpreting.
scala> isPalindrome("Madam, I'm Adam!")
res27: Boolean = true
9
Compound expressions

The code for isPalindrome looked like this:



The body of the method (the expression following the = sign) is a compound
expression
A compound expression consists of braces, {}, enclosing zero or more
expressions



def isPalindrome(s: String) = {
// several lines of code omitted…
string1.toLowerCase == string1.reverse.toLowerCase
}
If the braces are empty (zero expressions), the value is the unit, denoted ()
The value of a compound expression is the value of the last expression
evaluated in it
Hence, the value of the above method is the value of the expression
string1.toLowerCase == string1.reverse.toLowerCase
10
Palindromes IV

Just to neaten things up without changing how the program works (this is
called refactoring), here’s one more version:

def deleteNonLetters(s: String) = {
var result = ""
for (ch <- s) {
if (ch.isLetter) {
result = result + ch
}
}
result
}
def isPalindrome(s: String) = {
val temp = deleteNonLetters(s).toLowerCase
temp == temp.reverse
}
11
How I did it



I wrote the earliest, simple versions in the REPL
Once the method got long enough that I started making lots of
mistakes, I wrote it as a script
Here’s where I made most of my mistakes:




Forgetting to lowercase both the original and the reversed string
Forgetting to discard non-letters from both the original and the reversed
string
Simple typing errors (“typos”)
Also I forgot that, in a script, the deleteNonLetters method
must appear before it is used in isPalindrome

This careful ordering of methods isn’t required in a program
12
Testing

Of course, we have to test the method as we go along

scala> isPalindrome("A man, a plan, a canal--Panama!")
res5: Boolean = true
scala> isPalindrome("Anna")
res6: Boolean = true

scala> isPalindrome("")
res7: Boolean = true
And don’t forget:
scala> isPalindrome("success")
res8: Boolean = false
13
AtomicTest in the REPL



If you have installed the code supplied with the textbook, you have a very
simple test framework
Just enter this line:
import com.atomicscala.AtomicTest._
Then you can use tests of the form: method-call is expected-result

For example:
scala> isPalindrome("Anna") is true
true
scala> isPalindrome("Anne") is false
false
scala> isPalindrome("Anne") is true
false
[Error] expected:
true
14
AtomicTest in a script

Put this line at the very beginning of your script:
import com.atomicscala.AtomicTest._

Then put lines like this at the end of your script:
isPalindrome("Anna") is true
isPalindrome("A man, a plan, a canal--Panama!") is true
isPalindrome("Anne") is false

Here’s what is looks like in the REPL:
scala> :load Palindrome.scala
Loading Palindrome.scala...
import com.atomicscala.AtomicTest._
deleteNonLetters: (s: String)String
isPalindrome: (s: String)Boolean
true
true
false
15
The End
16