### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [SOLVED}Mystified by rules about parameter passing  (Read 470 times)

#### paul9531031

• New Member
• Posts: 13
##### [SOLVED}Mystified by rules about parameter passing
« on: March 19, 2020, 05:03:24 pm »
I am a total newbie - trying to learn Pascal.  I have a Function ChekInput, which is called by Procedure TForm1.DayExit, Day being a TLabeledEdit.  I can pass Day.Text as a parameter to ChekInput and it works, as shown below:
Code: Pascal  [Select][+][-]
1. Function ChekInput(var box: char; entry: string): boolean;
2. var d: integer;
3. begin
4.     res := true;
5.     try
6.        d := (StrToInt(entry));
7.     except
8.       box := 'E';
9.     end;
10.
11.     case (box) of
12.         'A' : if (d < 1) or (d > 31) then begin
13.         ShowMessage('Enter Day No from 1 to 31');
14.         res := false;
15.
16. // Lots of other lines
17.
18.         'E' : begin  res := false;
19.         ShowMessage('Enter only numbers')
20.         end;
21.      end;
22.     ChekInput := res;
23. end;
24.
25. procedure TForm1.DayExit(Sender: TObject);
26. begin
27.   c := 'A';
28.   if not (ChekInput(c, Day.Text)) then begin
29.   Day.SetFocus;
30.   Day.Text := ''
31.   end;
32. end;
33.
I have a Function HsMs, called by procedure TForm1.Stt1Exit, Stt1 being a TMaskEdit, which insists that I cannot pass Stt1.Text as a parameter, but must convert it to a string variable:
Code: Pascal  [Select][+][-]
1. Function HsMs(var entry: string): boolean;
2. var hr, mn: integer;
3. begin
4.    res := true;
5.    hr := StrToInt(Copy(entry,1,2));
6.    mn := StrToInt(Copy(entry,4,2));
7.    if (hr in [0..23]) and (mn in [0..59]) then exit
8.      else  res := false;
9.     HsMs := res;
10.  end;
11.
12. procedure TForm1.Stt1Exit(Sender: TObject);
13. var entry: string;
14. begin
15.   entry := Stt1.Text;
16.   if not (HsMs(entry)) then begin
17.    Stt1.SetFocus;
18.    Stt1.Text := '00.00'
19.   end;
20. end;
21.
Can anyone explain why these pairs behave dfferently please?
I am using Lazarus V 2.0.6 FPC 3.0.4 on Win 10 64 bit.
« Last Edit: March 23, 2020, 10:40:34 am by paul9531031 »

#### Remy Lebeau

• Hero Member
• Posts: 799
##### Re: Mystified by rules about parameter passing
« Reply #1 on: March 19, 2020, 05:14:45 pm »
In ChekInput(), the entry parameter IS NOT passed as a 'var' parameter, ie it is passed by value.  That is why any string value can be passed to it.

In HsMs(), the entry parameter IS passed as a 'var' parameter, ie it is passed by reference.  That is why you need an actual string variable to pass to it.

See var keyword and Variable parameter for more details.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

#### howardpc

• Hero Member
• Posts: 3481
##### Re: Mystified by rules about parameter passing
« Reply #2 on: March 19, 2020, 05:33:19 pm »
To add to Remy's reply: if you declared HsMs with a const string parameter or with no modifier rather than as a var parameter, you could pass parameters such as Stt1.Text.
BTW your routine would be more robust if you coded it something like this:
Code: Pascal  [Select][+][-]
1. function HsMs(const entry: String): Boolean;
2. var
3.   hr, mn: Integer;
4. begin
5.    Result := TryStrToInt(Copy(entry,1,2), hr) and TryStrToInt(Copy(entry,4,2), mn);
6.    case Result of
7.      True:  Exit((hr in [0..23]) and (mn in [0..59]));
8.      False: Exit;
9.    end;
10. end;
11.

#### paul9531031

• New Member
• Posts: 13
##### Re: Mystified by rules about parameter passing
« Reply #3 on: March 19, 2020, 06:26:14 pm »
Thank you Remy Labeau.  I had stupidly assumed that all parameter declarations began with var, and that it would apply to all the labels following it.
Thank you howardpc.  I was happy with non-robust routine because I have prior checks on what arrives into it.
BW Paul

#### Bart

• Hero Member
• Posts: 3850
##### Re: Mystified by rules about parameter passing
« Reply #4 on: March 19, 2020, 06:27:11 pm »
BTW your routine would be more robust if you coded it something like this:
Code: Pascal  [Select][+][-]
1. function HsMs(const entry: String): Boolean;
2. var
3.   hr, mn: Integer;
4. begin
5.    Result := TryStrToInt(Copy(entry,1,2), hr) and TryStrToInt(Copy(entry,4,2), mn);
6.    case Result of
7.      True:  Exit((hr in [0..23]) and (mn in [0..59]));
8.      False: Exit;
9.    end;
10. end;
11.

Why such a complicate Case Boolean of .. construct when you can simply do
Code: Pascal  [Select][+][-]
1. function HsMs(const entry: String): Boolean;
2. var
3.   hr, mn: Integer;
4. begin
5.    Result := TryStrToInt(Copy(entry,1,2), hr) and TryStrToInt(Copy(entry,4,2), mn) and
6.                   ((hr in [0..23]) and (mn in [0..59]));
7. end;

Shortcut Boolean evaluation (on by default) will ensure the second test will not be evaluated if TryIntToStr() fails.

Bart

#### howardpc

• Hero Member
• Posts: 3481
##### Re: Mystified by rules about parameter passing
« Reply #5 on: March 19, 2020, 08:43:03 pm »
Indeed, how right you are.

#### Remy Lebeau

• Hero Member
• Posts: 799
##### Re: Mystified by rules about parameter passing
« Reply #6 on: March 20, 2020, 03:12:26 am »
Shortcut Boolean evaluation (on by default) will ensure the second test will not be evaluated if TryIntToStr() fails.

Or, if you don't want to rely on short-circuiting being turned on:

Code: Pascal  [Select][+][-]
1. function HsMs(const entry: String): Boolean;
2. var
3.   hr, mn: Integer;
4. begin
5.   Result := TryStrToInt(Copy(entry,1,2), hr) and TryStrToInt(Copy(entry,4,2), mn);
6.   if Result then
7.     Result := (hr in [0..23]) and (mn in [0..59]);
8. end;
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)