3
$\begingroup$

I have written a function that relies on functions from an external library that may for various reasons fail to load. I would like to test if the functions in the external library have been defined before using them.

This seems like a natural approach:

NameQ["unloadedFxn"] (* returns False, as expected *)

and in isolation it works. Unfortunately, in practice, unloadedFxn appears within other functions, which causes it to be initialized.

otherFxn[x_] := 1 + unloadedFxn[x];

NameQ["unloadedFxn"] (* returns True, which is not what I want *)
                     (* because the function still hasn't been defined *)

Is there some other test that would let me see whether or not unloadedFxn has a definition?

[Addendum: I can kludge myself to a solution with ! ToString[Definition[unloadedFxn]] == "Null" but it feels inelegant. If you've got a cleaner solution, I'd love to hear it.]

$\endgroup$

2 Answers 2

6
$\begingroup$

If you don't mind using packages, then you can use HasDefinitionsQ from the GeneralUtilities package that comes with Mathematica:

Needs["GeneralUtilities`"]

HasDefinitionsQ[unloadedFxn]  (* False  *)

otherFxn[x_] := 1 + unloadedFxn[x]

HasDefinitionsQ[unloadedFxn]  (* False  *)

Which is what you want. Now, if you give it a definition, HasDefinitionsQ returns True:

unloadedFxn[a_, b_] := a + b

HasDefinitionsQ[unloadedFxn]  (* True  *)

Note: You can also call the function with a String instead of a Symbol e.g.

HasDefinitionsQ["unloadedFxn"]
$\endgroup$
2
  • $\begingroup$ How did you find this? I can't find it documented anywhere. $\endgroup$ Jan 25, 2017 at 22:06
  • $\begingroup$ @MichaelStern. It's not documented, I was looking for something else a few days ago in the package and accidentally stumbled on this function. $\endgroup$
    – RunnyKine
    Jan 25, 2017 at 22:14
0
$\begingroup$

Assuming you know how many parameters are gonna be defined you can do the following with ValueQ :

ClearAll[unloadedFxn]
otherFxn[x_] := 1 + unloadedFxn[x,y];
ValueQ[unloadedFxn[_]]
ValueQ[unloadedFxn[_, _]]

False

False

ClearAll[unloadedFxn]
unloadedFxn[a_, b_] := a+b
otherFxn[x_] := 1 + unloadedFxn[x,y];
ValueQ[unloadedFxn[_]]
ValueQ[unloadedFxn[_, _]]

False

True

Notice that only the second test evaluates to True since no functino is defined with one parameter in the form unloadedFxn[_]

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.