Search code examples
sashashtablefcmp

No guaranteed libname when hashing data in PROC FCMP


I'm using SAS' PROC FCMP to write some functions for recoding. These will be saved in a data set in a shared directory, so my coworkers can use them. Most of the time, the functions are just wrappers that hash a look-up table in the same directory.

Simplified example:

Libname OurStuff "path/to/shared/data";

DATA OurStuff.foobar;
    foo = 1;
    bar = 2;
Run;

PROC FCMP outlib = OurStuff.functions.lookup;
    Function recode_foo(foo);
        Length bar 8;
        Declare hash foobar(dataset: "OurStuff.foobar");
        rc = foobar.defineKey("foo");
        rc = foobar.defineData("bar");
        rc = foobar.defineDone();
        rc = foobar.find();
        Return(bar);
    Endsub;
Run;

The function works with the original libname:

Options cmplib = OurStuff.functions;
DATA _NULL_;
    result = recode_foo(1);
    Put result =;
Run;

But if somebody uses a different libname, it won't:

Libname OurStuff clear;
Libname WildName "path/to/shared/data";
Options cmplib = WildName.functions;

/* Results in "ERROR: Libref OURSTUFF is not assigned" */
DATA _NULL_;
    result = recode_foo(1);
Run;

Is there a way, other than insisting everyone uses the same libnames, to make sure these functions always work?


Solution

  • Since dataset is a string, it can be determined at runtime. Thus, you can pass it as a parameter to the function - either the libname, or (better) the whole dataset string.

    PROC FCMP outlib = OurStuff.functions.lookup;
        Function recode_foo(foo,dset $);
            Length bar 8;
            Declare hash foobar(dataset: dset);
            rc = foobar.defineKey("foo");
            rc = foobar.defineData("bar");
            rc = foobar.defineDone();
            rc = foobar.find();
            Return(bar);
        Endsub;
    Run;