Skip to main content
Engineering LibreTexts

1.10: Defining a New Method

  • Page ID
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    The advent of Test Driven Development1 has changed the way that we write code. The idea behind Test Driven Development, also called TDD or Behaviour Driven Development, is that we write a test that defines the desired behaviour of our code before we write the code itself. Only then do we write the code that satisfies the test.

    Suppose that our assignment is to write a method that “says something loudly and with emphasis”. What exactly could that mean? What would be a good name for such a method? How can we make sure that programmers who may have to maintain our method in the future have an unambiguous description of what it should do? We can answer all of these questions by giving an example:

    When we send the message shout to the string “Don’t panic” the result should be “DON’T PANIC!”.

    To make this example into something that the system can use, we turn it into a test method:

    Code \(\PageIndex{1}\) (Squeak): A Test For a Shout Method

        self assert: ('Don''t panic' shout = 'DON''T PANIC!')

    How do we create a new method in Squeak? First, we have to decide which class the method should belong to. In this case, the shout method that we are testing will go in class String, so the corresponding test will, by convention, go in a class called StringTest.

    \(\bigstar\) Open a browser on the class StringTest, and select an appropriate protocol for our method, in this case tests - converting, as shown in Figure \(\PageIndex{1}\). The highlighted text in the bottom pane is a template that reminds you what a Smalltalk method looks like. Delete this and enter the code from Code \(\PageIndex{1}\).

    The new method template in class StringTest.
    Figure \(\PageIndex{1}\): The new method template in class StringTest.

    Once you have typed the text into the browser, notice that the bottom pane is outlined in red. This is a reminder that the pane contains unsaved changes. So select accept (s) from the yellow-button menu in the bottom pane, or just type CMD–s, to compile and save your method.

    Because there is as yet no method called shout, the browser will ask you to confirm that this is the name that you really want — and it will suggest some other names that you might have intended (Figure \(\PageIndex{2}\)). This can be quite useful if you have merely made a typing mistake, but in this case, we really do mean shout, since that is the method we are about to create, so we have to confirm this by selecting the first option from the menu of choices, as shown in Figure \(\PageIndex{2}\).

    \(\bigstar\) Run your newly created test: open the SUnit TestRunner, either by dragging it from the Tools flap, or by selecting World ⊳ open... ⊳ Test Runner.

    The leftmost two panes are a bit like the top panes in the system browser. The left pane contains a list of system categories, but it’s restricted to those categories that contain test classes.

    \(\bigstar\) Select CollectionsTests-Text and the pane to the right will show all of the test classes in that category, which includes the class StringTest. The names of the classes are already selected, so click Run Selected to run all these tests.

    Accepting the testShout method class StringTest.
    Figure \(\PageIndex{2}\): Accepting the testShout method class StringTest.
    Running the String tests.
    Figure \(\PageIndex{3}\): Running the String tests.

    You should see a message like that shown in Figure \(\PageIndex{3}\), which indicates that there was an error in running the tests. The list of tests that gave rise to errors is shown in the bottom right pane; as you can see, StringTest>>#testShout is the culprit. (Note that StringTest>>#testShout is the Smalltalk way of identifying the testShout method of the StringTest class.) If you click on that line of text, the erroneous test will run again, this time in such a way that you see the error happen: “MessageNotUnderstood: ByteString>>shout”.

    The window that opens with the error message is the Smalltalk debugger (see Figure \(\PageIndex{4}\)). We will look at the debugger and how to use it in Chapter 6.

    The (pre-)debugger.
    Figure \(\PageIndex{4}\): The (pre-)debugger.

    The error is, of course, exactly what we expected: running the test generates an error because we haven’t yet written a method that tells strings how to shout. Nevertheless, it’s good practice to make sure that the test fails because this confirms that we have set up the testing machinery correctly and that the new test is actually being run. Once you have seen the error, you can Abandon the running test, which will close the debugger window. Note that often with Smalltalk you can define the missing method using the Create button, edit the newly-created method in the debugger, and then Proceed with the test.

    Now let’s define the method that will make the test succeed!

    \(\bigstar\) Select class String in the system browser, select the converting protocol, type the text in Code \(\PageIndex{2}\) over the method creation template, and accept it. (Note: to get a \(\uparrow\), type ˆ).

    Code \(\PageIndex{2}\) (Squeak): The Shout Method

        ↑ self asUppercase, '!'

    The comma is the string concatenation operation, so the body of this method appends an exclamation mark to an upper-case version of whatever String object the shout message was sent to. The \(\uparrow\) tells Squeak that the expression that follows is the answer to be returned from the method, in this case the new concatenated string.

    Does this method work? Let’s run the tests and see.

    \(\bigstar\) Click on Run Selected again in the test runner, and this time you should see a green bar and text indicating that all of the tests ran with no failures and no errors.

    When you get to a green bar2, it’s a good idea to save your work and take a break. So do that right now!

    The shout method defined on class String.
    Figure \(\PageIndex{5}\): The shout method defined on class String.

    1. Kent Beck, Test Driven Development: By Example. Addison-Wesley, 2003, ISBN 0–321–14653–0.

    2. Actually, you might not get a green bar since some images contains tests for bugs that still need to be fixed. Don’t worry about this. Squeak is constantly evolving.

    This page titled 1.10: Defining a New Method is shared under a CC BY-SA 3.0 license and was authored, remixed, and/or curated by Andrew P. Black, Stéphane Ducasse, Oscar Nierstrasz, Damien Pollet via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.