Příkaz with

vložil Radek Červinka 1. května 2013 01:56

S příchodem Delphi XE4 je with pro nové kompilátory (neoficiálně) deprecated. Zajímal by mne Váš názor v anketě (jako vždy vpravo nebo přes hlasov.at/l4ch.

Původně IMHO byl with koncipován jako hint kompilátoru, že by bylo vhodné být trošku efektivnější ohledně použití nějakého záznamu (později objektu). S tím, jak se jazyk rozšiřoval, začínalo docházet k riskantním situacím, viz. dále.

Jak jsem byl dříve velkým zastáncem with, tak se mu nyní snažím vyhýbat, jelikož už několikrát jsem tvrdě narazil. Klasickým případem může být kód kdy "vytknete" nějaký záznam nebo objekt, ale později ten záznam (objekt) někdo rozšíří o nějaký identifikátor, který se jmenuje jako identifikátor nadřízeného objektu (např. formuláře).

Mějme

type
  TMyRecord = record
    x, y: Integer;
  end;

var
  r: TMyRecord;
begin
  with r do
  begin
  // bla bla
    Caption := IntToStr(x);
  end;
end;  

Dejme tomu, že uvedený kód je ve formuláři - Caption je TForm.Caption. Prima, za běhu se změní titulek okna.

Nyní do TMyRecord (případně objektu) přidáme property (proměnnou) Caption. Kompilátor to bez problémů schroustne, my v pohodě dáme program zákazníkovi a je hotovo. Přesně stejná situace nastala, když to TRect přibyla (počítaná) property Width a Height. Pokud člověk nebyl opatrný - byl problém na světě.

Takže za sebe mohu říct - ANO.

Tagy: ,

Jazyk

Komentáře

1.5.2013 10:31:22 #

oxo

I With se dá používat (více) bezpečně. Já se třeba snažím všechny identifikátory, které nepatří pod with, jednoznačně přidělit. Tvůj kód by byl:

with r do
begin
  // bla bla
  Self.Caption := IntToStr(x);
end;

Pak ten problém s Caption nenastane.

oxo

1.5.2013 17:16:53 #

kaco

Dufam ze Embarcadero tento nezmyselny napad rychlo opusti.
Neviem presne co Radek mysli pod terminim hint kompilatoru, ale podla definicie jazyka pascal, je with zlozeny prikaz. Opisane s prace Niklaus Wirth z jula 1973 (str 25), krasne starodavne cyklostilovane skripta :)

<structured statement> ::= <compound statement> | <conditional statement> | <repetitive statement) |<with statement>

Kompilator by nemal "schroustnout" nejednoznacny kod. Slusne by bolo keby aspon warning vypustil. Riesit to  redukovanim definicie jazyka sa mi zda barbarske. Logickejsie by bolo upravit kompilator.

// kusok aktualneho kodu. inicializacia tms tlacitka
// s with
with launchButton.Status do begin
Caption := VersionString;
with Appearance.Fill do begin
   BorderColor := clGray;
   Rounding := 8;
   ShadowOffset := 0;
end;
with Appearance.Font do begin
   Color := clWhite;
   Height := -10;
   Name := 'Tahoma';
end;
end;

// bez with
launchButton.Status.Caption := VersionString;
launchButton.Status.Appearance.Fill.BorderColor := clGray;
launchButton.Status.Appearance.Fill.Rounding := 8;
launchButton.Status.Appearance.Fill.ShadowOffset := 0;
launchButton.Status.Appearance.Font.Color := clWhite;
launchButton.Status.Appearance.Font.Height := -10;
launchButton.Status.Appearance.Font.Name := 'Tahoma';

kaco

1.5.2013 18:19:41 #

JaroB

Poprvé jsem narazil na chyby s with v Delphi 2005 a to v konstrukcích typu
with AnyObject.Create(AOwner) do
begin
   anyproperty := anyvalue;
   ...
end;
kdy kompilátor špatně přiřadil fly objekt resp. místo toho sem-tam používal self.
Potíž byla v tom, že se o nebezpečném přiřazení nic nehlásilo a taky že stejný kód, který bezpečně chodil v Delphi 7 se zachoval záludně. Delphi 2006 tuto chybu již nemělo (nebo ne v takovém rozsahu), chovalo se to korektně jako v Delphi 7 (ale mělo to zase jiné internal errors, když bylo přiřazení víc jak tisíc v bloku atp.).

with je docela dobrá konstrukce např. pro záznamy, ale pro objekty bude asi bezpečnější použít lokální proměnné, no nevím :(
Každopádně mi vadí, že kompilátor nic nehlásí v konstrukcích
with obj, rec, rec2, obj2 do
když narazí na stejný název položky ve více objektech (a někdy je problém zjistit, jestli opravdu platí pravidlo zleva doprava, čí že to je vlastně položka)

JaroB

1.5.2013 18:51:26 #

pepak

Mě se řešení s deprecated líbí, zvlášť pokud to "deprecated" zůstane neomezeně dlouho - je to signál, že by bylo vhodné ten kód opravit, ale nikoho to nenutí, aby to opravdu dělal.

pepak

1.5.2013 22:02:06 #

radekc

Myslím, že jsem jasně napsal, že se to týká nových kompilátorů (platform pokud to není jasné).

>Kaco:
Budeš se divit až TMS například Caption ze Status přesune někam jinam, protože se jim to bude hodit. Nic nepoznáš - a to je přesně ten případ.

Správné IMHO je deklarovat lokální proměnnou typu co je ten status nebo Appearance.

radekc

2.5.2013 2:56:07 #

kaco

>radekc
Ano, pochopil som co si pisal. Ja som hovoril o definicii pascalu,  nie o konkretnom kompilatore. Dokonca tam bola vyzva ze Ta zaujima co si myslim(e). Tak este napisem co si myslim.
Dal som priklad ktory mal ukazat, preco pokladam konstrukciu with za zmysluplnu. Ak sa pouziva s rozumom zlepsuje citatelnost kodu.
To ze kazda vizualna komponenta ma property Caption, je problem navrhu komponenty, nie problem konstrukcie with.
Ak by TMS presunulo Caption alebo ho nebodaj premenovalo na StatusCaption, dufam ze kompilator hociktorej platformy , dokonca aj nextgen to zisti. Ten moj kod nie je sucastou ziadnej dalsej, nadradenej, komponenty ktora ma property Caption.

kaco

2.5.2013 9:46:40 #

radekc

> Ten moj kod nie je sucastou ziadnej dalsej, nadradenej, komponenty ktora ma property Caption.

No ale může být použit na formuláři, který má Caption ne? To je jen pro upřesnění. Pochybuji, že někdy v dohledné době with z Win32 zmizi.

radekc

2.5.2013 10:49:01 #

RadekV

Myslim ze With je jen o neco mensi peklo nez GoTo

RadekV

2.5.2013 12:10:04 #

bullhead

Jen taková osobní úvaha...

Konečně! Nic v Pascalu mně tak nes...o jako "WITH" (v cizích kódech, sám bych to nikdy nepoužil). Už jsem se tu o tom kdysi zmiňoval. A osobně mne těší, že nejen já, jak vidím, si myslí, že ta konstrukce prostě musí zmizet. Na to, jak je Pascal "ukecaný" a zároveň "čitelný" (taky se proto používal na výuku programování, btw by mne zajímalo jestli se na něm ještě lidi učí), koncept "WITH" neuvěřitelně znepřehleďnoval kód. Beru to také jako "malé osobní vítězství":-), musím zavolat kolegovi z kterým jsem se před pár lety o této "chybě" Pascalu Xkrát hádal:-)))).

Pokud jsem přebíral cizí programy, druhé co jsem dělal (po rozjetí cest a komponent) bylo okamžitě odstranění "WITH" bloků. Až mne děsilo, kolik lidí ho používalo - vlastně dodnes nechápu proč, aby se ušetřilo pár písmenek kódu? Někomu ty "microbloky" připadali čitelnější? Sám jsem to sice nikdy nepoužil, ale věřím, že ve speciálních případech i kompiler z toho musel být někdy zmatený (a jak vidím výše v příspěvcích, taky občas byl).

A add "deprecated". To nepovažuji za moc dobré řešení:-(. Kdysi jsem se živil Javou, a tam, díky špatnému vstupnímu návrhu a neustálým změnám (identická situace je dnes z Androidem), projekt který byl v lednu přeložen bez jediného warningu  měl v prosinci na novější Javě desítky "deprecated" hlášek. Nikdo to nebude opravovat. Nikdo na to nebude mít v dnešní hektické době čas. Prostě se to hlášení vypne a tak to udělá 90 procent lidí (nebo se rovnou ty hlášky prostě budou ignorovat a lidi si na ně zvyknou). Ano, pokud by se direktně zakázalo "WITH" používat, na začátku při přechodu na novou verzi to přidělá trochu problémů (prostě se ty bloky přepíši), a musel by se asi počkat až totéž udělají tvůrci komponent, ale už by byl navždy klid.

B.

p.s. ...to RadekV: +1! ...hned za "GoTo"!

bullhead

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců