Using/With/Try&Finally/... or similar

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
DarkDragon
Addict
Addict
Posts: 2218
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Using/With/Try&Finally/... or similar

Post by DarkDragon »

Hello,

As we currently discuss the Try/Catch, there is a very connected keyword in other languages that I would suggest for PureBasic. In C# it is Using, in python it is With. If we cannot have Try/Catch, we may still have a kind of centralized clean up inside of scopes.

It looks like this:

Code: Select all

Using *Buffer[ = AllocateMemory(...)]
  ; use buffer
EndUsing
it is equal to

Code: Select all

[*Buffer = AllocateMemory(...)]
Try
  ; use buffer
Finally
  ; Clean up the object
  FreeMemory(*Buffer)
EndTry
So when leaving the scope, the buffer will be released automatically. In situations similar to the following two two it is useful, otherwise you'd have to care about cleaning up resources inside the If-blocks in this scope every single time:

Code: Select all

; Situation 1
Procedure Whatever()
  Using *Buffer
    ...
    If something
      ...
      ProcedureReturn ...
    EndIf
    ...
    If something
      ...
      ProcedureReturn ...
    EndIf
    ...
  EndUsing
EndProcedure

; Situation 2
For i = 0 To 20
  Using *Buffer
    ...
    If something
      ...
      Break
    EndIf
    ...
    If something else
      ...
      Continue
    EndIf
    ...
  EndUsing
Next
However, the FreeMemory is somewhat too static, so a kind of destructor should be called instead. As PureBasic is not object oriented so much, a destructor call for each object would be kind of inconsistent and you may need to access variables of the outer scope anyway during cleanup. So I would prefer the Finally construct instead, even if Catch may not be implemented (in the near future).
bye,
Daniel
User avatar
Sicro
Enthusiast
Enthusiast
Posts: 538
Joined: Wed Jun 25, 2014 5:25 pm
Location: Germany
Contact:

Re: Using/With/Try&Finally/... or similar

Post by Sicro »

+1

Without a native solution is probably not much more possible than that:

Code: Select all

Macro CleanUp(_Object_)
  
  If IsGadget(_Object_)   : FreeGadget(_Object)
  ElseIf IsFile(_Object_) : CloseFile(_Object_)
  ElseIf IsFont(_Object_) : FreeFont(_Object_)
  ElseIf _Object_ > 0     : FreeMemory(_Object_)
  EndIf
  
EndMacro


Macro Using(_Object1_=-1, _Object2_=-1, _Object3_=-1, _Object4_=-1, _Object5_=-1, _Object6_=-1, _Object7_=-1)
  
  CompilerIf Not Defined(ObjectsCollector, #PB_List)
    NewList ObjectsCollector()
  CompilerEndIf
  
  If _Object1_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object1_
  EndIf
  
  If _Object2_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object2_
  EndIf
  
  If _Object3_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object3_
  EndIf
  
  If _Object4_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object4_
  EndIf
  
  If _Object5_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object5_
  EndIf
  
  If _Object6_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object6_
  EndIf
  
  If _Object7_ <> -1
    AddElement(ObjectsCollector())
    ObjectsCollector() = _Object7_
  EndIf
  
EndMacro


Macro EndUsing
  ForEach ObjectsCollector()
    CleanUp(ObjectsCollector())
  Next
EndMacro


File    = CreateFile(#PB_Any, GetTemporaryDirectory() + "Temp")
Font    = LoadFont(#PB_Any, "Arial", 12)
*Memory = AllocateMemory(1024)

Debug "--- Before using ---"
Debug "File:   " + IsFile(File)
Debug "Font:   " + IsFont(Font)
Debug "Memory: " + PeekB(*Memory)

Using(File, Font, *Memory)
  ; ...
  ; Do something
  ; ...
EndUsing

Debug ""
Debug "--- After using ---"
Debug "File:   " + IsFile(File)
Debug "Font:   " + IsFont(Font)
Debug "Memory: " + PeekB(*Memory)
Image
Why OpenSource should have a license :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (syntax color scheme) :: RegEx-Engine (compiles RegExes to NFA/DFA)
Manjaro Xfce x64 (Main system) :: Windows 10 Home (VirtualBox) :: Newest PureBasic version
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 794
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: Using/With/Try&Finally/... or similar

Post by Zebuddi123 »

Hi to All. I think Macro`s in general are a Penicillin of Antibiotics and I really like these little brain teasers, Although I not so good I do like trying to solve the problem/s and it takes far more thought and analysis than Procedures. Give you another way of thinking. @Sirco I like your solution Gone straight into my templates :)

Zebuddi. :)
malleo, caput, bang. Ego, comprehendunt in tempore
DarkDragon
Addict
Addict
Posts: 2218
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: Using/With/Try&Finally/... or similar

Post by DarkDragon »

Sicro wrote:Without a native solution is probably not much more possible than that[...]
Yes exactly, we cannot even ensure that it is being executed when we leave the scope. So EndUsing always has to be reached in your code, which is not the sense of it. Put a ProcedureReturn, Break, Continue, ... inside and EndUsing won't be executed.
bye,
Daniel
Post Reply