When we call a SAS hash object method, we can either call it assigned or unassigned. Sometimes it doesn’t matter what style is used. But most of the time it does. This post describes the difference between an assigned and an unassigned method call and why the difference is important.
The Unassigned Call
The unassigned hash object call assigns no return code to a variable. Nor does it check the return value of the method to take any further action. It simply calls the method. While the syntax is nice and simple, the unassigned call can be dangerous. Consider the following code snippet. Here, I declare and instantiate a hash object. Next, I call the Add() Method unassigned twice. The first is fine. However, the second one yields an error in the log because the hash object was declared without the Multidata:’Y’ argument tag. The Error does not terminate the data step. However, some will yield terminating errors.
data _null_; k=.; d=.; declare hash h(); h.defineKey('k'); h.defineData('d'); h.defineDone(); h.add(key:2, data:2); h.add(key:2, data:4); run;
The Assigned Call
Next, let us run the exact same code. This time, I call the methods assigned. I assign the return value to the variable rc. This time, no error message is written to the log. Instead, the relevant information is held in the rc variable. The first method call is successful, which gives a rc value of zero. The second method call in unsuccessful, which gives a non-zero return code.
data _null_; k=.; d=.; declare hash h(); h.defineKey('k'); h.defineData('d'); h.defineDone(); rc=h.add(key:2, data:2); put rc=; rc=h.add(key:2, data:4); put rc=; run;
As we saw in the first code snippet, the error message from an unsuccessful hash object method call does not always terminate the data step. However, sometimes it does. Let us take a look at an example. Below, I create a hash object with a corresponding iterator object. Then, I let the iterator dwell on the first item in the hash object. In hash object lingo, the iterator locks the item group that it currently dwells on. That means that the relevant item group can not be removed or cleared. Any attempt to do so yields a terminating error message. To demonstrate, I call Clear() unassigned.
If you look in the log, you will see an error message which states that the data step was aborted during execution.
data _null_; k=.; d=.; declare hash h(); h.defineKey('k'); h.defineData('d'); h.defineDone(); declare hiter hi('h'); rc=h.add(key:2, data:2); hi.first(); h.clear(); *h.delete(); run;
A Rule of Thumb
The above code examples raises the natural question: What methods should be called assigned and unassigned respectively? A nice rule of thumb is this. When a hash object method can fail, you should call is assigned. When a hash object by construction can not fail, there is no need to do so. It simply looks messy. Furthermore, it underlines the fact that you understand the hash object, when you only do assigned calls when it is actually necessary. Two nice examples of method calls that can not fail (i.e they can not return a non-zero return code) are the Ref() and Replace() Methods.
Below, I have listed the SAS hash object method that I usually call assigned and unassigned respectively. Naturally, it always depends on the actual circumstances. However, it is nice to have a general rule of thumb to rely on.
In this post, I have demonstrated the difference between an assigned and an unassigned hash object method call in SAS. It is important to know when to call a method assigned and when not to. We have seen a few examples of how to avoid error messages in the log and take the necessary precautions when a method call is unsuccessful. Furthermore, I have made a rule of thumb for what methods are usually called assigned and which ones are usually called unassigned.
If you are interested in learning about the hash object, see the blog posts 5 Tips to Learn and Understand the Hash Object in SAS and 6 Reasons Why The SAS Hash Object Fails. Also, did you know that you can use the Hash Object in PROC FCMP?
You can download the entire code from this example here.