Announcement

Collapse
No announcement yet.

Variablename$

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Variablename$

    This is nothing really important, but out of curiosity i want to know, if it is possible to mimic a "Variablename$", which works similar to "Funcname$" and returns the name of a variable by passing only the variable. Obviously, if the name of a variable is "n", i could code <any string varaible> = "n". But if e.g for debugging purposes i wanted to show the name and the value of this variable, i would have to pass two paramters to my macro or function.

    Is it possible to pass only the variable and derive its name inside a function or macro, so i would have to pass only the variable itself ?


    This is what i tried (without success) so far:


    Code:
    '***********************************************************************************************
    ' To Do
    '
    '***********************************************************************************************
    
    
    #COMPILE EXE "test.exe"
    #DIM ALL
    
    
    '***********************************************************************************************
    ' this works, but i must type two parameters: "n" for y, and n for x
    '***********************************************************************************************
    
    
    Macro test(y, x)
    macrotemp t1
    dim t1 as string
    
    
      t1 = y + " =" + str$(x)
      msgbox t1,,"test"
    
    
    end macro
    
    
    '***********************************************************************************************
    ' obviously this cannot work ...
    '***********************************************************************************************
    
    
    Macro test1(x)
    macrotemp t1
    dim t1 as string
    
    
      t1 = x                                              'must make x a literal string, but how ...
      msgbox t1,,"test"
    
    
    end macro
    
    
    '***********************************************************************************************
    ' how to create a literal string from a macro parameter
    '***********************************************************************************************
    
    
    macro dqq = "
    'macro dqq = ""
    'macro dqq = """
    'macro dqq = """"
    
    
    Macro test2(x)
    macrotemp t1
    dim t1 as string
    
    
    '  t1 = dqq                                            'test what is returned by dqq
      t1 = dqq x dqq                                      'replace "dqq" with a $DQ should work
      msgbox t1,,"test"
    
    
    end macro
    
    
    '***********************************************************************************************
    
    
    FUNCTION PBMAIN () AS LONG
    '***********************************************************************************************
    ' main
    '***********************************************************************************************
    local n as long
    
    
      n = 4
    
    '  test("n", n)                                        'works
    '  test1(n)                                             'doesn´t, but this is what i want (somehow...)
      test2(n)                                             'doesn´t either (in fact neither of all the variations does)
    
    
    END FUNCTION
    
    
    '***********************************************************************************************
    '***********************************************************************************************
    '***********************************************************************************************


    A macro seems suitable for this task, but i failed to create a literal string from a macro parameter - any other/better ideas ?


    Thanks


    JK

  • #2
    but out of curiosity i want to know, if it is possible to mimic a "Variablename$", which works similar to "Funcname$"
    Um, no.

    Consider
    Code:
    FUNCTION Foo ( Bar as LONG) AS LONG
    All of these would be valid ways to call this function..

    Code:
      Z = Foo (12&)
      Z =  Foo (A)
      Z =  Foo ( CLNG(B)) 
      Z  = Foo ((A))
      Z =  Foo (A * B)
    What should variablename$ be reported as when executing function 'Foo?'

    If you can do anything at all, it's going to to be with some sort of MACRO.

    But my question is, why the heck would you want this at all? We do have this....
    But if e.g for debugging purposes i wanted to show the name and the value of this variable..
    .. but that sure as heck is not the only way to do that.

    But If it's just for debugging...

    Code:
    
    FUNCTION ShowVarValue ( X AS LONG, varname as string) As LONG
    #IF %DEF (%DEBUGME)
          MSGBOX   USING$ ( "variable '&'  has value #",  varname, x
    #ENDIF
    END FUNCTION
    ....
    
    CALL showVarValue (  Q, "Q")  ' show name and value of variable 'Q'
    That code does nothing unless the equate "%Debugme" is defined.

    MCM
    Michael Mattias
    Tal Systems Inc.
    Racine WI USA
    mmattias@talsystems.com
    http://www.talsystems.com

    Comment


    • #3
      Hi MCM,

      thanks for your reply!

      If you can do anything at all, it's going to to be with some sort of MACRO.
      I agree, but i didn´t want to bias or narrow possible solutions/answers to what i thought might be the way to go.

      Forgive me my lazyness, of course there are many solutions and workarounds (see the macro "test" in my code), but all require more typing. The problem isn´t how to solve it at all, but to sove it with the least typing effort. I just wanted to know, if there is a "minimal" approch (just typing the variable) for it.

      As mentioned above this isn´t really a decisive matter, it is just playing around and maybe finding a better or more elgant solution for something, which basically is already solved - just for the fun of it.


      JK

      Comment


      • #4
        Hi Juergen

        Thank you for raising this matter

        I do a large amount of data processing with lots of headings and I would really like this function too.

        I often think about it.

        Silly and trivial, but what I do in PBCC is:

        Type Print variable
        Then control D
        Then change the first variable to "variable ";

        Sometimes I have to do this for 20 variables. It is my main debug tool!

        In some slightly more complex situations, I use macros.

        But as you say you have to have

        macroname ("variable",variable)

        which is a minor pain

        Kerry
        [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
        Kerry Farmer

        Comment


        • #5
          Sometimes I have to do this for 20 variables. It is my main debug tool!
          One man's opinion, but if you need to watch/output twenty (20) variables to debug one thing, I think you need to look at your program design. There has got to be a way to use procedures to make that number a tad more manageable.

          MCM


          Michael Mattias
          Tal Systems Inc.
          Racine WI USA
          mmattias@talsystems.com
          http://www.talsystems.com

          Comment


          • #6
            A working solution with a (most of times acceptable) downside:


            Code:
            '***********************************************************************************************
            ' To Do
            '***********************************************************************************************
            
            
            #COMPILE EXE "test.exe"
            #DIM ALL
            
            
            '***********************************************************************************************
            
            
            Macro test(x)
            '***********************************************************************************************
            ' works, but you cannot have "DATA" statements inside a procedure you are using it !  ...and
            ' it cannot be called more than 16384 times (the regular usage limit would be 2°16 - 1
            '***********************************************************************************************
            macrotemp pp__ts
            MACROTEMP h
            MACROTEMP i__i
            macrotemp pp__vt
            dim pp__ts as string
            dim pp__vt as Variant
            dim i__i as dword
            
            
              DATA x~h
                                                                  'set data at compile time, = variablename + counter
                                                                  'data acepts literal strings without quotation !!!
              i__i = 1
              WHILE i__i <= DATACOUNT
                pp__ts = READ$(i__i)
                IF RIGHT$(pp__ts,4)=HEX$(&h,4) THEN EXIT LOOP
                i__i = i__i + 1
              WEND
            
            
              pp__ts = extract$(READ$(i__i), "~")                 'get data record
            
            
              pp__vt = x                                          'store into a variant
            
            
              SELECT CASE VARIANTVT(pp__vt)
                CASE 8                                            'string
                  IF pp__ts = VARIANT$(pp__vt) THEN
                    pp__ts="<"+pp__ts+">"
                  ELSE
                    pp__ts = pp__ts + " = "+CHR$(34)+VARIANT$(pp__vt)+CHR$(34)
                  END IF
            
                CASE ELSE                                         'numeric (could make more branches for different numerics)
                  pp__ts = pp__ts + " = " + FORMAT$(VARIANT#(pp__vt),18)+"   "+ _
                                           HEX$(VARIANT#(pp__vt),8)+" (Hex)"
              END SELECT
            
            
              msgbox pp__ts,,"test"
            
            
            END MACRO    
            
            
            '***********************************************************************************************
            
            
            FUNCTION PBMAIN () AS LONG
            '***********************************************************************************************
            ' main
            '***********************************************************************************************
            local n as long
            local teststring$
            
            
              n = 4
              teststring$ = "asdf"
            
              test(n)                                             'works
              test(teststring$)                                   'works
            
            
            END FUNCTION
            
            
            '***********************************************************************************************
            '***********************************************************************************************
            '***********************************************************************************************


            This works, as long as you don´t have "DATA" statements inside a procedure you are using it and it cannot be called more than 16384 times. A regular macro usage limit would be 2°16 - 1.

            Any better solution without these restrictions would be appreciated...



            JK


            Comment


            • #7
              Originally posted by Michael Mattias View Post
              Um, no.

              Consider
              Code:
              FUNCTION Foo ( Bar as LONG) AS LONG
              All of these would be valid ways to call this function..

              Code:
              Z = Foo (12&)
              Z = Foo (A)
              Z = Foo ( CLNG(B))
              Z = Foo ((A))
              Z = Foo (A * B)
              What should variablename$ be reported as when executing function 'Foo?'
              Code:
              "<NotVariable>"
              "A"
              "<NotVariable>"
              "<NotVariable>"
              "<NotVariable>"
              He asked about variables, other things like equations or literals are not relevant to the question. But i like your MACRO idea Michael.

              Originally posted by Michael Mattias View Post
              But my question is, why the heck would you want this at all? We do have this....

              .. but that sure as heck is not the only way to do that.

              But If it's just for debugging...
              A variety of reasons. Probably none of which you have encountered yet. I know the answer is not directet to me, but i have
              also needed to do this.

              My Solution was to create a table of VARPTR's.

              So, when calling VARIABLENAME$(MyVariable$) the function returns "MYVARIABLE" optionally adding the data symbol (also for variables with no data symbol).

              The thing is that under some circumstances the VARPTR's change, so, the key is to have the list updated.
              www.pluribasic.com

              Comment


              • #8
                Originally posted by Michael Mattias View Post

                One man's opinion, but if you need to watch/output twenty (20) variables to debug one thing, I think you need to look at your program design. There has got to be a way to use procedures to make that number a tad more manageable.
                Forgive me oh guru

                But the '20' can be required if you are doing complex relationships between 20 data items (including function input and output fields). It is not an opinion, it is a fact. I admit 20 would be a lot but 5 or 10 are quite common in my programs. And more than one set are required for several decision places around the program.

                These sequences are often commented out or partially commented out or copied to other places as the program develops. In most cases they are deleted from the final version of the code.

                I also use the same technique for print totals at the end of the program. These totals are a 'realism' check and as such are a debugging/checking tool. These totals are also used for user information purposes (I run the programs for my users, so they do not see the totals as such)

                Occasionally, it is convenient to put data in an array to save coding, but this does not really get around the problem

                My approach requires me to have realistic and informative data file names, but again with complex data relationships, such names are very helpful (or even necessary) anyway

                [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                Kerry Farmer

                Comment


                • #9

                  I admit 20 would be a lot but 5 or 10 are quite common in my programs....
                  There's a big difference between '5 or 10' and '20.'

                  Occasionally, it is convenient to put data in an array to save coding,
                  Call me contrary, but occasionally it is necessary to add source code - 'waste' coding if you will - in the interest of making the program testable.

                  Just sayin', if I had something like that to create, test and debug, I would design with "testability" as a required feature. Without an example, I don't think it's possible to suggest alternatives to watching twenty vars, but just off the top of my head the PB stepping debugger can do this.

                  But I was rereading this thread. What is the INPUT to the 'variablename$' function? Just the symbol??

                  e.g.
                  Code:
                  LOCAL A AS LONG
                  yadda yadda
                  'debug line
                      MSGBOXLIKE_FUNCTION  (A)   ' show   "Variable 'A' has value 12345"
                  ..
                  Is that all you want?

                  MCM
                  Michael Mattias
                  Tal Systems Inc.
                  Racine WI USA
                  mmattias@talsystems.com
                  http://www.talsystems.com

                  Comment


                  • #10

                    @MCM

                    Is that all you want?
                    Yes!

                    ...but occasionally it is necessary to add source code...
                    I absolutely agree, but as i´m a lazy guy, i want to type as little as possible. As Kerry said above, it is only a "minor pain" but a generic solution would make life easier in that respect...


                    @Brian

                    what you describe is of course possible, but it would require preliminary steps (setup a list of variables used in this procedure) and it would require keeping this list up to date. This is doable, but it is not what i want. I want to be able to insert "test(var_name)" anywhere inside a procedure, without any other requirements or dependencies. Where "var_name" is the name (symbol) of a variable and "test(..." outputs this name and the corresonding value of the variable with this name.


                    JK

                    Comment


                    • #11
                      I want to be able to insert "test(var_name)" anywhere inside a procedure, without any other requirements or dependencies.
                      Without one of the workarounds mentioned (or similar) No it is not possible.

                      Variable names and procedure names do not exist in the compiled code. Nor do you want them to exist if you think about it. (speed probably down, size up for sure)

                      FUNCNAME$ does not return the name of the function or sub either. It returns the ALIAS. If an alias is not defined by the coder, it returns the default alias. While the ALIAS is often the same, or similar to, the procedure name; it does not have to be.

                      Perhaps an Interpreter could be written that does what you want.. Then the source code containing the names would always be available.
                      Dale

                      Comment


                      • #12
                        Originally posted by Juergen Kuehlwein View Post
                        @Brian

                        what you describe is of course possible, but it would require preliminary steps (setup a list of variables used in this procedure) and it would require keeping this list up to date. This is doable, but it is not what i want. I want to be able to insert "test(var_name)" anywhere inside a procedure, without any other requirements or dependencies. Where "var_name" is the name (symbol) of a variable and "test(..." outputs this name and the corresonding value of the variable with this name.
                        My solution requires NO manual preliminary steps. A precompilng step takes care of that. But if you do not want to pre-process the code, then the only solution is that it is done at compile-time by PowerBASIC.

                        Good luck with that, since it is not a functionality very widely required, i doubt it will be implemented, but if it does, i will be the first to jump in joy.

                        www.pluribasic.com

                        Comment


                        • #13
                          @Dale


                          it is possible - see post #6 (ok - with some restrictions)


                          @Brian


                          pre-processing is possible and i do a lot of it in my IDE, but i was hoping (and still hope) for an easier solution...


                          Comment


                          • #14
                            Within the context of a program at run time, variable names are resolved to addresses.
                            They have absolutely no meaning.
                            If you want meaningful variable names to be included as part of your data handling, you
                            might consider using a UDT rather than passing individual datum.
                            This will require rewriting your code to accommodate awareness of specific UDT members.
                            The world is strange and wonderful.*
                            I reserve the right to be horrifically wrong.
                            Please maintain a safe following distance.
                            *wonderful sold separately.

                            Comment


                            • #15
                              Originally posted by Michael Mattias View Post



                              Call me contrary, but occasionally it is necessary to add source code - 'waste' coding if you will - in the interest of making the program testable.

                              Just sayin', if I had something like that to create, test and debug, I would design with "testability" as a required feature. Without an example, I don't think it's possible to suggest alternatives to watching twenty vars, but just off the top of my head the PB stepping debugger can do this.

                              But I was rereading this thread. What is the INPUT to the 'variablename$' function? Just the symbol??
                              Absolutely

                              I certainly do design my code with testing in mind - very much so. For instance that is one of the reasons that I name my fields very descriptively and I use naming standards within the program.

                              And program structure is very important to testing and debugging but we all know this. I am quite strict on having subroutines which will fit on a single screen page.

                              I also use macros to ensure consistency in my code. Once you get the macro coded right, you no longer have to think about it.

                              I also think very carefully through how I will lay out the names in the global section of my program to help my understanding and also to check for errors by running my eye down the names etc

                              Some of my programs are quite complex. I would use 'waste coding' as you say quite a lot for testing and checking purposes. In fact it would not surprise me if I sometimes use as much waste coding as non-waste coding. The waste coding gets deleted sometimes after I have debugged that bit and sometimes after I have finished the program. I am not embarrassed about this approach.

                              Sometimes I comment out my waste coding and move it to the bottom of my program in case I need it again. So I have to document the waste code too.

                              Some of my waste coding is printing out variables before and after I do 'something'. So the before variables are input to 'something' and the after variables are output of the 'something'. The 'something' is usually a code sequence but is not a defined thing.

                              I guess I called it a function but I did not mean a PB function - please excuse my terminological inexactitude.

                              The waste code also does a WAITKEY$ or in some cases does a WAITKEY$ if some_counter mod 20 (say) = 0. Sometimes I use a 'SLEEP' instead of a WAITKEY$

                              So technique 1 is casual prints before and after doing something.

                              Technique 2 is to spill out data onto a file which I then analyse usually with excel. Sometimes this data is before and after data too. And for this purpose too it would be good to have a variablename$ function.

                              I often put create csv files with headings and the variablename$ option may be useful there.

                              But I am not stressing. I had wondered about asking if anyone else had this issue over the years and whether there was any solution. I was delighted when Juergen (a person who I suspect knows far more about PB than I so) raised the matter.

                              In my ignorance about how compilers work, I would have thought that you could say #variable_name_option_on, and the compiler could keep a list of variable names and their addresses in the program. So when you ask for a variable name to be printed, the compiled program would have access to the information - maybe in some sort of parameter file. Sure this might slow things down, but when the program is working, you would have the option about turning the variable name switch off. But anyway, in 90% of my programs speed is irrelevant and the natural speed of my PB code is sufficient (although there are exceptions to this rule in my portfolio).

                              But I stand by my comment, which was kindly seconded by Juergen, that it is a minor pain.


                              [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                              Kerry Farmer

                              Comment


                              • #16
                                I would have thought that you could say #variable_name_option_on, and the compiler could keep a list of variable names and their addresses in the program
                                A LOCAL variable's address could be different every time the procedure containing it is called, depending on the route taken to get there.
                                Michael Mattias
                                Tal Systems Inc.
                                Racine WI USA
                                mmattias@talsystems.com
                                http://www.talsystems.com

                                Comment


                                • #17
                                  How about:

                                  Code:
                                  #COMPILE EXE
                                  
                                  TYPE VLONG
                                      Value AS LONG
                                      Name  AS STRING * 32
                                  END TYPE
                                  
                                  
                                  FUNCTION PBMAIN AS LONG
                                  
                                  LOCAL Variable AS LONG        ' Pre-process as : LOCAL Variable as VLONG : Variable.Name = "Variable"
                                  
                                  Variable = 25                 ' Pre-Process as Variable.value = 25
                                  
                                  PRINT VARIABLENAME$(Variable) ' Pre-Process as PRINT TRIM$(Variable.Name)
                                  
                                  END FUNCTION
                                  Restrictions: It would not work with arrays or array elements. String elements would have a limit length, because STRING UDT members cannot be dynamic length.
                                  www.pluribasic.com

                                  Comment


                                  • #18
                                    Originally posted by Michael Mattias View Post

                                    A LOCAL variable's address could be different every time the procedure containing it is called, depending on the route taken to get there.
                                    Naturally, I bow to your greater knowledge

                                    But how does the debugger do it then????
                                    [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                                    Kerry Farmer

                                    Comment


                                    • #19
                                      Originally posted by Kerry Farmer View Post

                                      Naturally, I bow to your greater knowledge

                                      But how does the debugger do it then????
                                      The debugger uses the debug data stored with the program.
                                      In the case of PowerBASIC, it generates a Programname.EXE.PBD file.
                                      I just tested it. A small program that compiles to a 54K .exe comes out
                                      as a 7.3M .exe.pbd file. All the variable names and other data absent at
                                      run time are included in that file.
                                      The world is strange and wonderful.*
                                      I reserve the right to be horrifically wrong.
                                      Please maintain a safe following distance.
                                      *wonderful sold separately.

                                      Comment


                                      • #20
                                        Originally posted by Kurt Kuzba View Post

                                        The debugger uses the debug data stored with the program.
                                        In the case of PowerBASIC, it generates a Programname.EXE.PBD file.
                                        I just tested it. A small program that compiles to a 54K .exe comes out
                                        as a 7.3M .exe.pbd file. All the variable names and other data absent at
                                        run time are included in that file.
                                        There we are then

                                        That is the way that variablename$ would work

                                        You might have to say
                                        #variable_name_is_on
                                        [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                                        Kerry Farmer

                                        Comment

                                        Working...
                                        X