Now the basics of what can be put in a method have been explained we can move on to building new methods.
As was shown by the main method in the previous examples, a method has a name, argument types, and a return type. The name can consist of more than a single part, in which case each part must be followed by an argument---remember how the out method of the stdio class does not need any arguments.
For instance, in the following example, the method's name is multiply by;
int multiply int a by int b { return a * b; } |
This method accepts two arguments, each of type int, and returns another int. The body of the method simply returns the result of multiplying a and b.
Notice how every name part of the method starts on a new line, and that the nameparts are right justified. This is considered a readable style of writing method declarations. It is much more readable than written like this:
int multiply int a by int b { return a * b; } |
To test our multiply by method we add it to the example program, between the start and the end of the class implementation, and test it using the following main method:
int main Array argv { int i, n = [argv length], result = 1; for (i = 0; i < n; i++) { String s = [argv at i]; result = [self multiply result by [s intValue]]; } [[[stdio out] print result] nl]; return 0; } |
The receiver of the multiply by message is self. self is an implicit argument to every method; it is the receiver of the message which caused invocation of the method. In this example, self is the HelloWorld class object.
This example also shows the use of a String object, which is retrieved from the array argv. An Array stores the objects it holds in a sequence, and using the at message, one can ask for the object at a certain index, as long as the index is within range, in this case 0 <= index < [argv length].
The full declaration of the at method is
Any at int index; |
That is, an Any object is returned and since we know it is a String, we are allowed to assign the value returned to a String. In fact, as the name Any suggests, we can assign an Any to a variable of any class.
In the example, the String s is asked for its intValue. intValue is a String method which returns the integer value held by the string, in a straightforward way. For example, when asked for its intValue, the string "123abc" will return 123, "abc" will return 0, and "0x123abc" will return 1194684.
It is customary for method name parts to use mixed case identifiers, starting with a lowercase letter. Class names also follow the mixed case convention, but they start with a capital letter. Variables should be all lower case, with the words within the identifier separated by `-' or `_'.
When recompiled, the hello program will, when run, output the result of multiplying its arguments.
$ ./hello 23 2 46 $ ./hello 1 $ ./hello 123456789 98 -786136566 |
The program behaves as expected, apart from the last example. Two positive numbers, when multiplied should return a positive number. However, when 123456789 is multiplied by 98 the answer, 12098765322, is too large to fit a signed 32 bits value, which is the int used for the result and the multiply by method. Obviously, the problem can be shifted to the 64 bits limit by using long values, but that is not a real solution; it is important that you realise the existence of such limits.