Written by

Question Ruslan K · Jul 23, 2017

Check if class exists

There is method:

$System.OBJ.New( ClassName As  %String = "" )

If class with name ClassName exists - everything is OK.

But, when class does not exist, there is error - <CLASS DOES NOT EXIST>

How can I check before calling $System.OBJ.New() if class witn name ClassName exists?

Comments

Robert Cemper · Jul 23, 2017

set exist=##class(%Dictionary.CompiledClass).%ExistsId(ClassName)

will tell you the status

0
Rubens Silva  Jul 24, 2017 to Dmitry Maslennikov

Though it works, it's not literal: another programmer could ask himself why you tested the method %New, thus requiring to add a comment for explaining it. However if you use ExistsId, you're literally saying about testing if the class exists.
I know, it's just a detail, but still contributes for clean code directives.

0
Robert Cemper  Jul 25, 2017 to Eduard Lebedyuk

so you may use $$$comClassDefined(class)  for compile classes

or go for ^oddCOM(....)

0
Eduard Lebedyuk  Jul 25, 2017 to Mikhail Khomenko

That's $$$defClassDefined(class). It shows that class definition exists (or doesn't), but it doesn't show if a class is compiled.

0
John Murray  Aug 7, 2017 to Luca Ravazzolo

Luca, any reason for recommending %Exists and having to use $LISTBUILD when you could go direct to %ExistsId ?

0
Dmitry Maslennikov · Jul 24, 2017

Check if method %New exists with this function

$system.CLS.IsMthd(ClassName, "%New")
0
Robert Cemper  Jul 24, 2017 to Rubens Silva

I'm fully with you.
Using hidden %System.whatever   Classes is as bad practice as using undocumented $zu(anynumber,  ,  , )

0
Rubens Silva  Jul 24, 2017 to John Murray

That is because the  CLS Package is used internally.
InterSystems uses it to verify if the method is defined or not without throwing exception.
This is probably faster than %ExistsId, because %ExistsId tries to open the instance beforehand instead.

0
Dmitry Maslennikov  Jul 24, 2017 to Rubens Silva

I think it even works without any COS code, just like any other system functions. And they have more than just only IsMthd.

0
Rubens Silva  Jul 24, 2017 to Eduard Lebedyuk

You're right, %Dictionary.CompiledClass actually overwrites the current %Persistent implementation for %Exists (which is called by %ExistsId).

0
Jeffrey Drumm  Jul 24, 2017 to Eduard Lebedyuk

@Eduard, where is the macro $$$comClassDefined defined?

0
Eduard Lebedyuk  Jul 24, 2017 to Rubens Silva

%ExistsId does not open an object for %Dictionary package. Just checks the globals (see %Dictionary.CompiledClass for example).

The fastest way to check if a class exists would be:

write $$$comClassDefined(class)
0
Robert Cemper  Jul 25, 2017 to Rubens Silva

And if you also want to be sure that also the Method %New exists you my use

write $$$comMemberDefined(ClassName,"m","%New")

[just reading through %occReference.inc]

0
Mikhail Khomenko · Jul 25, 2017

mgstat.int uses such approach (in this case, for class %SYSTEM.CPU):

if $D(^oddDEF("%SYSTEM.CPU")) {
        ...
    }

0
Luca Ravazzolo · Aug 7, 2017

Use the official and documented API.

If pure existence or simply the class is defined (but not compiled)

SAMPLES>w ##class(%Dictionary.ClassDefinition).%Exists($lb("Aviation.Aircraft"))
1

If you're after existing and compiled:

SAMPLES>w ##class(%Dictionary.CompiledClass).%Exists($lb("Aviation.Aircraft"))
​1

--

HTH

0
Robert Cemper · Aug 14, 2017

Pls. don't forget to mark your question as "answered" on Developer Community,
please click the checkmark alongside the answer you (as author of the question) accept

0