Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • r-class program to return an empty result

    Dear All, I have the following code (example) that I expect to always return r(val):
    Code:
    clear all
    version 17.0
    
    program define foobar, rclass
        syntax , p(integer)
        if `p'>=0 return local val=char(96)+"BIG"+char(39)
        else return local val=""
    end
    But when the value is empty, the r(val) seems to be not defined at all after the run and this causes complications down the stream for me. Is there a way to force-define the returned result as an empty string?

    Thank you, Sergiy

  • #2
    How is it causing complications downstream? Even though you will not see an r(val) in the output of -return list-, the kinds of things one might normally do with a returned empty string seem to work:
    Code:
    . clear all
    
    . version 17.0
    
    .
    . program define foobar, rclass
      1.     syntax , p(integer)
      2.     if `p'>=0 return local val=char(96)+"BIG"+char(39)
      3.     else return local val=""
      4. end
    
    .
    .
    . foobar, p(-1)
    
    . return list
    
    .
    . assert missing(r(val))
    
    . assert "`r(val)'" == ""
    
    . display "|`r(val)'|"
    ||
    
    . display  ="{" + "`r(val)'" + "}"
    {}
    
    .

    Comment


    • #3
      Hello Clyde:

      if I do something like:
      Code:
      assert r(val)==char(96)+"BIG"+char(39)          /* my preferred way of checking */
      then its equivalent breaks for the empty value:
      Code:
      assert r(val)==""             /* results in an error when no value is returned for r(val) */
      If I switch to asserts of the type:
      Code:
      assert `"`r(val)'"'==""
      then the following assert fails where it was true before:
      Code:
      assert `"`r(val)'"'==char(96)+"BIG"+char(39)
      So far I involve Mata to do a verification in a standardized form:

      Code:
      mata assert(st_global("r(val)")==char(96)+"BIG"+char(39))
      mata assert(st_global("r(val)")=="")
      but clearly this is something I'd rather avoid.

      Thank you, Sergiy

      Comment


      • #4
        It looks like setting any macro to the empty string deconstructs the macro by design. Scalars can be set to the empty string, but for whatever reason to return a scalar, the expression must evaluate to a number or missing. So you're between a rock and a hard place here. Scalars do make it into the global scope though, so you could globalize this like so:

        Code:
        clear all
        version 17.0
        
        program define foobar, rclass
            syntax , p(integer)
            if `p'>=0 scalar val=char(96)+"BIG"+char(39)
            else scalar val=""
        end
        
        foobar, p(1)
        return list, all
        scalar list
        di val
        
        foobar, p(-1)
        return list, all
        scalar list
        di val
        Code:
        . foobar, p(1)
        
        . return list, all
        
        . scalar list
               val = `BIG'
        
        . di val
        `BIG'
        
        .
        . foobar, p(-1)
        
        . return list, all
        
        . scalar list
               val =
        
        . di val
        
        
        .
        Of course, globalizing data isn't always ideal, but this may be one option.
        Last edited by Daniel Schaefer; 28 Jul 2023, 11:56. Reason: tweaking minor details

        Comment


        • #5
          I do not think the problem is not with empty (null) strings; I think the problem is with having a non-dereferenced local maco inside an r() macro. The only reason

          Code:
          assert `"`r(val)'"'==char(96)+"BIG"+char(39)
          fails is because you want the literal string `BIG' not the dereferenced local macro BIG. Why would you even want to do something like that?

          Comment


          • #6
            The only reason ... fails is because you want the literal string `BIG' not the dereferenced local macro BIG. Why would you even want to do something like that?
            Because it is part of the user input obtained outside of Stata and must be retained verbatim in all subsequent processing, without any conscious attempt or accidental possibility of being evaluated as a Stata macro. The content may include any number or combination of mismatched quotes, dollar signs and anything else that the users feel like typing or copying from a document.

            foobar is just a minimal example to illustrate the point.

            So you're between a rock and a hard place here.
            That's exactly how I am feeling...

            Thank you, Sergiy

            Comment


            • #7
              Originally posted by Sergiy Radyakin View Post
              Because it is part of the user input obtained outside of Stata and must be retained verbatim in all subsequent processing, without any conscious attempt or accidental possibility of being evaluated as a Stata macro. The content may include any number or combination of mismatched quotes, dollar signs and anything else that the users feel like typing or copying from a document.
              Are you sure Stata is the best language for the job? You might be better of with some other language -- including Mata if you want to stick with the Stata software.

              Comment

              Working...
              X