sql >> Databáze >  >> RDS >> Access

Pozor na to, na co se díváte

Onehdy jsem narazil na tuto odpověď na StackOverflow a chtěl jsem na ni upozornit (zdůrazňuji můj):

Tento problém se mi projevil při ladění, když měl jsem hodinky, které se pokusily vrátit položku „chybějícího“ klíče . Ve skutečnosti další frustrované ladění mělo stejný problém, když jsem doslova sledoval [scriptingdictonaryObject].exists() condtional); Navrhuji, aby ten „chybějící“ klíč byl přidán kvůli hodinkám . Když jsem odstranil hodinky a místo toho vytvořil dočasný list, do kterého jsem pole zkopíroval za běhu, nechtěné klíče již nebyly přidány.
Objekt slovníku přidávající položky před .add() se nazývá Používám objekt slovníku z knihovny MS Scripting Runtime k uložení řady polí a provádění operací s buňkami pole podle potřeby. Procesem prochází smyčka for... Stack Overflowriddley_w

Co se tady děje?

Jednou z „vlastností“ objektu Dictionary je to, že bude implicitně vytvářet nové položky, aniž byste museli volat metodu .Add explicitně . Jaký je rozdíl mezi implicitním a explicitním?

Poznámka:Včasné použití objektu Dictionary vyžaduje odkaz na "Microsoft Scripting Runtime" (podrobnosti zde).

Dim MyDict As New Dictionary

'Explicit add
MyDict.Add "KeyA", "Item A"

'Implicit add
MyDict.Item("KeyB") = "Item B"

Debug.Print MyDict("KeyA"); vbNewLine; MyDict("KeyB")

Zde je relevantní část dokumentace týkající se implicitní vytvoření klíče:

Poznámky
Pokud klíč nebyl nalezen při změně položky , nový klíč je vytvořen pomocí zadaného newitem . Pokud klíč nebyl nalezen při pokusu o vrácení existující položky, nový klíč je vytvořen a jeho odpovídající položka je ponechána prázdná.

Reprodukce problému

Zopakujme si problém, abychom přesně viděli, kde věci jdou stranou.

Očekávané chování

Vytvořte následující ukázkovou rutinu:

Sub WatchOut()
    Dim MyDict As Dictionary
    Set MyDict = New Dictionary
    
    Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub

Spusťte výše uvedenou rutinu z bezprostředního okna a měla by vrátit hodnotu False:

WatchOut
KeyA exists? False

Přidat hodinky

Nyní přidáme hodinky položky „KeyA“:

Zkusme spustit WatchOut znovu rutina:

WatchOut
KeyA exists? False

Zatím je vše dobré. Možná to nakonec není problém.

Projděte si kód

Přidejme Zastávku příkaz k vynucení přerušení kódu:

Sub WatchOut()
    Dim MyDict As Dictionary
    Set MyDict = New Dictionary
    
    Stop
    Debug.Print "KeyA exists? "; MyDict.Exists("KeyA")
End Sub

Nyní zkusme spustit WatchOut rutina:

WatchOut
KeyA exists? True

Aha! Kombinace hodinek a nabourání se do debuggeru stačí k tomu, aby se „štěnice“ objevila. Dal jsem chybu v děsivých uvozovkách, protože je to vlastně očekávané chování ladicího programu. Pro vývojáře je to ale téměř jistě neočekávané chování.

(Upozorňujeme, že na Stop není nic zvláštního příkaz, který toto chování způsobuje. Můžete odstranit Stop řádek a nastavte bod přerušení v kódu a dojde ke stejnému chování.)

Můžete vidět, kde by vám taková věc mohla způsobit vytrhávání vlasů při ladění. Kdykoli se chování vašeho programu při normálním běhu liší od chování při ladění, máte předpoklady pro jednu přitěžující relaci ladění.

Shrnutí

Kroky pro reprodukci problému:

  1. Vytvořte sledování pro konkrétní položku ve slovníku
  2. Při spouštění kódu se prolomte do ladicího programu

To pravděpodobně pomůže pouze jednomu nebo dvěma vývojářům. Ale potenciálně to těmto vývojářům ušetří hodiny frustrace. A abych byl upřímný, je pravděpodobné, že jako kdokoli jiný budu jedním z těchto vývojářů;-).


  1. Uvedeno APPL_TOP v Oracle Applications R12

  2. Rozdíl mezi čtením potvrzeným a opakovatelným čtením

  3. Automatizované testování záloh PostgreSQL

  4. Oracle PL/SQL:Dynamický příklad SQL pomocí okamžitého spuštění