DATA Step, Macro, Functions and more

Why does this work ?

Reply
N/A
Posts: 1

Why does this work ?

** no "and" in condition -seems to be assumed **;  

%macro check;

   %if      %sysfunc(fileexist("&PV1."))

       not %sysfunc(fileexist("&PV2."))

      %then %do ;

        %put "hello";

      %end;

  %put outside;

%mend;

%let pv1=<path/filename1>;

%let pv2=<path/filename2>;

%check;

Respected Advisor
Posts: 3,777

Re: Why does this work ?

Because 0 not 0 is equal to 1.

17         %put NOTE: %eval(0 not 0);
NOTE: 1
PROC Star
Posts: 7,360

Re: Why does this work ?

DN: Can you explain that for me/us?

Yes, I know that is the result that SAS gives, but I don't know why.  I ran the following and got the following result:

  %put NOTE1: %eval(0 not 0);

  %put NOTE2: %eval(0 not 1);

  %put NOTE3: %eval(1 not 1);

  %put NOTE4: %eval(1 not 0);

results in:

NOTE1: 1

NOTE2: 0

NOTE3: 0

NOTE4: 1

I can see the answers, but have no idea what is being compared.

Respected Advisor
Posts: 3,777

Re: Why does this work ?

I don't know that I can explain it, at least not logically. :smileyshocked:  I refer you to SAS Operators in Expressions

PROC Star
Posts: 7,360

Re: Why does this work ?

I vote for an error in the %eval function.  I did read that section in the documentation and realize that not is supposed to be an operator, but the following won't work in a data step:

data test;

  x1=0 not 0;

  x2=0 not 1;

  x3=1 not 1;

  x4=1 not 0;

run;

Conversely, the following will run in a SAS macro:

%macro check;

   %if      %sysfunc(fileexist("&PV1."))

       not %sysfunc(fileexist("&PV2."))

      %then %do ;

        %put "hello";

      %end;

  %put outside;

  %put NOTE1: %eval(0 not 0);

  %put NOTE2: %eval(0 not 1);

  %put NOTE3: %eval(-0 not 1);

  %put NOTE4: %eval(-0 not 0);

%mend;

%let pv1=<path/filename1>;

%let pv2=<path/filename2>;

%check

and will produce:

"hello"

outside

NOTE1: 1

NOTE2: 0

NOTE3: 0

NOTE4: 1

methinks that %eval() is only looking at the not 0 and not 1 parts and ignoring whatever comes before the 'not'.  As a test of that hypothesis, the following works and provides the same result as the previous macro?

%macro check;

   %if      %sysfunc(fileexist("&PV1."))

       not %sysfunc(fileexist("&PV2."))

      %then %do ;

        %put "hello";

      %end;

  %put outside;

  %put NOTE1: %eval("cc" not 0);

  %put NOTE2: %eval("xx" not 1);

  %put NOTE3: %eval("yy" not 1);

  %put NOTE4: %eval("zz" not 0);

%mend;

%let pv1=<path/filename1>;

%let pv2=<path/filename2>;

%check

Valued Guide
Posts: 2,174

Re: Why does this work ?

As an aide to clarity

NOT

Is not the same operator as

NE

and the effect is quite different

PROC Star
Posts: 7,360

Re: Why does this work ?

Peter,

In case I didn't make myself clear in my last post, I think the reason it works is that %eval has an unaddressed fault that is allowing erroneous code to run without returning an error.  As is, given a use like %eval("cc" not 0); the only thing being returned is the answer to "not 0" which would be 1. The first value (in this case "cc") isn't even being considered.

Art

Ask a Question
Discussion stats
  • 6 replies
  • 321 views
  • 0 likes
  • 4 in conversation