Hey there, Uniface developers! π
If you've been working with Uniface for a while (or are just diving in), you've probably stumbled across the term "Handle". Maybe you've seen it in documentation, or perhaps a senior dev mumbled something about "passing the handle" and vanished into a coffee break. βπββοΈ
Today, let's demystify what a Handle actually is, why you need it, and how to use it without tying your code into knots! πͺ’
π€ What is a Handle anyway?
In simple terms: A Handle is a reference.
Think of it like a pointer or a unique ID card for something that exists in your application's memory at runtime. πͺͺ It's not the object itself, but it's the key to accessing it.
In Uniface, Handles are used to reference dynamic runtime objects like:
- Component Instances (a running Form, Service, or Report) ποΈ
- Entities (tables/collections in memory) π
- Occurrences (specific rows/records) π
Instead of hardcoding names or guessing where an instance lives, you grab its Handle. With that Handle, you can say: "Hey Uniface, perform this operation on exactly THIS specific instance!"
π οΈ Why use Handles?
Why not just use names? Well, names are static. Handles are dynamic and cool! π
- Loose Coupling: Your components don't need to know everything about each other. They just need a Handle to talk. π£οΈ
- Multiple Instances: Imagine you have 5 instances of the same Service running. How do you talk to the 3rd one? By its Handle! π’
- Cleaner Code: Passing a Handle is cleaner than passing around long strings of names or keys. π§Ή
π» Show me the code!
Here is a classic scenario. You want a Service to do some work and return a reference (Handle) to itself or another object so you can use it later.
1. Defining a Handle Parameter (Uniface 10+)
Since Uniface 10, we have a dedicated handle data type. Use it! It makes your code type-safe and easier to read. π‘οΈ
operation CreateWorker
public
parameters
public handle p_WorkerHandle : out
endparameters
variables
handle v_Instance
endvariables
; Create a new instance of a service
newinstance "SVC_WORKER", v_Instance
; Return the handle to the caller
p_WorkerHandle = v_Instance
end
2. Using that Handle
Now the caller has the Handle and can command that specific worker instance. π·ββοΈ
operation MainController
variables
handle v_MyWorker
endvariables
; Get the handle
call SVC_FACTORY.CreateWorker(v_MyWorker)
; Use the handle to call an operation on that specific instance!
; This is the magic part β¨
v_MyWorker->DoHardWork("Fix bugs π")
; Don't forget to clean up if you're done (if needed)
deleteinstance v_MyWorker
end
β οΈ Watch out for these traps!
- Dangling Handles: If you delete an instance (
deleteinstance), the Handle you held becomes useless. Trying to use it afterwards is like trying to call a phone number that's been disconnected. π΅π₯ - Not for Databases: Handles are runtime memory addresses (sort of). DO NOT save them into a database column. They won't work tomorrow or even in the next session. π«πΎ
π― Summary
- Handle = A dynamic reference to a runtime object (Instance, Entity, Occurrence).
- Use the
handledata type in Uniface 10+. - They are perfect for managing multiple instances and decoupling your code.
- Never store them permanently!
I hope this clears up the fog around Uniface Handles! Now go forth and newinstance with confidence! πβ¨
Happy coding! π»π₯
Top comments (0)