Recent

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
    • Lebeau Software
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
    • Bart en Mariska's Webstek
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
    • Lebeau Software
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)

 

TinyPortal © 2005-2018