Ah.
The difference is whether the function is a
method of the TMainForm class or not.
A quick tutorial:
Forward declarations vs. automatic declarations
Normally you might have a program that looks like this:
program foo;
function triple_it( x: real ): real;
begin
triple_it := x *3
end;
var
number: real;
begin
write( 'Please enter a number to be tripled> ' );
readln( r );
writeln( r, ' tripled is ', triple_it( r ) )
end.
In this little program, we have both
declared and
defined a function named "triple_it". By declaring, we mean that we have told the compiler that it exists. By defining, we mean that we have told the compiler all the details about it. Typically, as in this example, things are declared at the same time they are defined. That is, by defining a thing we implicitly declare it as well.
In Pascal, a thing
must be at least declared before it is used.
Sometimes, however, we need to tell a program that something exists before we actually define it. Hence, we need to use a
forward declaration. Here's a simplistic example lifted off of the Wikipedia (and repaired for correctness):
program oddness;
function is_it_even( n: integer ): boolean; forward;
function is_it_odd( n: integer ): boolean;
begin
if n = 1
then is_it_odd := TRUE
else is_it_odd := is_it_even( n -1 )
end;
function is_it_even;
begin
if n = 1
then is_it_even := FALSE
else is_it_even := is_it_odd( n -1 )
end;
var x: integer;
begin
write( 'Please enter a whole number greater than zero> ' );
readln( x );
writeln( 'The statement "', x, ' is odd" is ', is_it_odd( x ), '.' );
writeln( 'The statement "', x, ' is even" is ', is_it_even( x ), '.' )
end.
Notice how we used the function "is_it_even"
before we defined it? We told the compiler about it beforehand using the
forward keyword. That is, we declared it. Thereafter we only needed to define it somewhere in the program.
This is how a
unit works. They have an
interface section, wherein things are
declared, and an
implementation section, wherein things are
defined.
(If anyone here is using Extended Pascal and wants to know how this looks in a
module, post here and I'll post with the details.) Here's a unit that provides the two functions:
unit oddstuff;
interface
function is_it_even( n: integer ): boolean;
function is_it_odd( n: integer ): boolean;
implementation
function is_it_odd;
begin
if n = 1
then is_it_odd := TRUE
else is_it_odd := is_it_even( n -1 )
end;
function is_it_even;
begin
if n = 1
then is_it_even := FALSE
else is_it_even := is_it_odd( n -1 )
end;
end.
And the program that uses it:
program oddness;
uses oddstuff;
var x: integer;
begin
write( 'Please enter a whole number greater than zero> ' );
readln( x );
writeln( 'The statement "', x, ' is odd" is ', is_it_odd( x ), '.' );
writeln( 'The statement "', x, ' is even" is ', is_it_even( x ), '.' )
end.
One thing to note is that in the definition of the procedures/functions, you only needed to name it. You did not need to specify all the parameters and the like. Typically Borland IDEs and variations will duplicate the procedure/function header with the definition. Both have to match exactly. But it is not strictly necessary to duplicate the declaration with the definition.
A
class is always described in two parts: a declaration part and a definition part. (This separation is necessary, but I'll not go into details as to why here.) The declaration looks like you are used to seeing:
type
tMatrix = class
private
f_rows, f_cols: integer;
f_elements: array of array of extended;
public
constructor create( rows, cols: integer );
function get_element( row, col: integer ): extended;
procedure set_element( row, col: integer; value: extended );
end;
In the definition, you must fully qualify the name of the methods of the class, otherwise the compiler thinks you are talking about some
other procedure named (e.g.) "set_element" --not the method of the class.
So our definitions may be:
constructor tMatrix.create( rows, cols: integer );
begin
f_rows := rows;
f_cols := cols;
setLength( f_elements, f_rows, f_cols )
end;
function tMatrix.get_element( row, col: integer ): extended;
begin
result := f_elements[ row, col ]
end;
procedure tMatrix.set_element( row, col: integer; value: extended );
begin
f_elements[ row, col ] := value
end;
In each instance, I had to prefix the name of the class to the name of the method, so that the forward declaration is satisfied. If I had just said:
function get_element( row, col: integer ): extended;
begin
result := f_elements[ row, col ]
end;
The compiler would have complained, saying:
I don't have a function named "get_element". (The only thing I've got so far is a class named "tMatrix".)
Since the get_element function is a member of tMatrix, we must use its full name.
Well, I hope this explains things better.