Gebrauch von With

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gebrauch von With

Beitrag von Mathias »

hier wird anscheinend immer der zuletzt aufgeführte Parameter benutzt.

Das ',' ersetzt folgende Schreibweise:

Code: Alles auswählen

with Button1, Button2 do 
// ist gleich:
with Button1 do with Button2 do
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Form schliessen und wieder öffnen

Beitrag von Warf »

m.fuchs hat geschrieben:Wenn du Blöcke abtrennen möchtest, dann verwende doch einfach mal Methoden.

Aber ich finde es gut, dass die Diskussion aufgekommen ist. So konnte ich gleich mal meine Code-Quality-Checks um ein Verbot von with...do erweitern. :mrgreen:


Da kann man aber auch eins meiner Lieblings pascal features verwenden, geschachtelte Methoden:

Code: Alles auswählen

procedure TFooBar.Foo(Params);
type
  // Typen
var
  // Variablen
const
  // Konstanten
 
// Subfunktionen:
  procedure Bar(Params2);
  //...
  begin
  end;
 
type
  // Typen
var
  // Variablen
const
  // Konstanten
begin
  Bar(Params to be passed);
end;


Die Funktion Bar hat damit zugriff auf alles was oberhalb dieser Funktion definiert wurde (also die ersten Variablen, Typen und Kosntanten, sowie die Parameter von Foo), hat dabei eigene Variablen typen und konstanten (sowie weitere Funktionen und Parameter) die in Foo unzugänglich sind, und die Typen, konstanten und variablen die drunter definiert werden sind nicht zugänglich.

Um Methoden aufzuteilen sehr hilfreich wenn man die Submethoden ansonsten nicht braucht. Z.B. auch sehr hilfreich für Rekursionen:

Code: Alles auswählen

procedure QuickSort(Arr: TIntegerArray);
  procedure QuickSortHelper(H, L: Integer);
  begin
    // Qicksort auf arr
  end;
begin
  QuickSortHelper(High(Arr), Low(Arr));
end;

Da von außen die Helperfunktion mit High und Low nicht gebraucht wird muss sie ja nicht für andere Methoden sichtbar sein

m.fuchs hat geschrieben:Ja, da ist das in Visual Basic.NET wirklich sauberer gelöst.

Ja das wäre deutlich schöner. Kaum zu glauben das Visual Basic in irgendetwas sauberer ist.

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: Form schliessen und wieder öffnen

Beitrag von theo »

Warf hat geschrieben:Da kann man aber auch eins meiner Lieblings pascal features verwenden, geschachtelte Methoden:

Der Unterschied ist, wenn man geschachtelte Methoden verwendet, dann weiß man meist warum man das tut und passt entsprechend auf "wie ein Haftelmacher".
"With" hingegen wird oft aus (schlechter) Gewohnheit verwendet bzw. weil man glaubt, man sei damit irgendwie cool (bis es einen in den Hintern tritt). :wink:

P.S. Mir ist noch ein weiteres Argument gegen "with" eingefallen. Es ist nicht "Refactoring sicher".
Angenommen ich verwende in einer Methode meines Hauptformulars eine Klasse, welche eine Eigenschaft "Caption" hat mit "with"

Code: Alles auswählen

With MyObj do Caption:='With ist blöd';

und entschließe mich später in der Klasse, diese Eigenschaft "Title" zu nennen, dann kompiliert das fröhlich weiter, ändert dann aber die Caption des Formulars.
Das ist ein weiterer, komplett unnötiger Fallstrick.

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gebrauch von With

Beitrag von Mathias »


Findest du da with immer noch blöd ?

Code: Alles auswählen

  WriteLn(
    'RedPrc: ', Image1.Picture.Bitmap.RawImage.Description.RedPrec,
    ' RedShift: ', Image1.Picture.Bitmap.RawImage.Description.RedShift,
    ' GreenPrec: ', Image1.Picture.Bitmap.RawImage.Description.GreenPrec,
    ' Green: ', Image1.Picture.Bitmap.RawImage.Description.GreenShift,
    ' BluePrec: ', Image1.Picture.Bitmap.RawImage.Description.BluePrec,
    ' BlueShift: ', Image1.Picture.Bitmap.RawImage.Description.BlueShift);
// oder
  with Image1.Picture.Bitmap.RawImage.Description do begin
    WriteLn('RedPrc: ', RedPrec, ' RedShift: ', RedShift,
      ' GreenPrec: ', GreenPrec, ' Green: ', GreenShift,
      ' BluePrec: ', BluePrec, ' BlueShift: ', BlueShift);
  end;
 

Schlussendlich muss jeder selbst entscheidenden, was besser ist. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Gebrauch von With

Beitrag von wp_xyz »

Mathias hat geschrieben:Findest du da with immer noch blöd ?

Obwohl ich bezüglich "with" nicht so puritanisch eingestellt bin, wie manche meiner Vor-"Poster", und gelegentliches "with" (wenn alles klar ist) zulasse, hätte ich das nie so gemacht, sondern hätte stattdessen eine Zwischenvariable deklariert, die mir im Fall des Falles auch einfachen Zugriff durch den Debugger erlaubt:

Code: Alles auswählen

var
  desc: TRawImageDescription;
...
  desc := Image1.Picture.Bitmap.RawImage.Description;
  WriteLn(
    'RedPrc: ', desc.RedPrec,
    ' RedShift: ', desc.RedShift,
    ' GreenPrec: ', desc.GreenPrec,
    ' Green: ', desc.GreenShift,
    ' BluePrec: ', desc.BluePrec,
    ' BlueShift: ', desc.BlueShift);
 

oder evtl noch eine Stufe höher, um auch die anderen Properties des RawImage im Debugger einfach sehen zu können;

Code: Alles auswählen

var
  img: TRawImage;
...
  img := Image1.Picture.Bitmap.RawImage;
  WriteLn(
    'RedPrc: ', img.Description.RedPrec,
    ' RedShift: ', img.Description.RedShift,
    ' GreenPrec: ', img.Description.GreenPrec,
    ' Green: ', img.Description.GreenShift,
    ' BluePrec: ', img.Description.BluePrec,
    ' BlueShift: ', img.Description.BlueShift);
 

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gebrauch von With

Beitrag von Mathias »

sondern hätte stattdessen eine Zwischenvariable deklariert, die mir im Fall des Falles auch einfachen Zugriff durch den Debugger erlaubt:
Dir ist aber bewusset, das du etwas mehr als nur einen Pointer kopierst ?

Code: Alles auswählen

var
  desc: TRawImageDescription;
  img: TRawImage;
begin
  WriteLn(SizeOf(desc)); // --> 68
  WriteLn(SizeOf(img)); // --> 120

Bei dem Writeln spielt es keine Rolle, aber wen du diese Description-Bezeichner änderst, wird diese nur lokal geändert und nicht in Image1.

TRawImageDescription + TRawImage sind keine Classen, sondern statische Objecte.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Gebrauch von With

Beitrag von mse »

Auf die Gefahr hin dass ich mich wiederhole:
Free Pascal braucht eine sichere "with" Variante.
Es wird seit über zehn Jahren immer wieder diskutiert und Luca Olivetti zeigt jeweils einen uralt Pascal Dialekt der ein entsprechendes Konstrukt zur Verfügung stellt - alles ohne Wirkung.

Mathias
Beiträge: 6165
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Gebrauch von With

Beitrag von Mathias »

mse hat geschrieben:Auf die Gefahr hin dass ich mich wiederhole:
Free Pascal braucht eine sichere "with" Variante.
Es wird seit über zehn Jahren immer wieder diskutiert und Luca Olivetti zeigt jeweils einen uralt Pascal Dialekt der ein entsprechendes Konstrukt zur Verfügung stellt - alles ohne Wirkung.

Sowas wäre in dieser Art wäre doch eine Lösung:

Code: Alles auswählen

  {$NewWidth}
  with Canvas do begin
    .Line(0, 0, 100, 100);
  end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10468
Registriert: Mo 11. Sep 2006, 19:01

Re: Gebrauch von With

Beitrag von theo »

mse hat geschrieben:Auf die Gefahr hin dass ich mich wiederhole:
Free Pascal braucht eine sichere "with" Variante.

Ja, da gebe ich dir recht.

Antworten