Results 1 to 3 of 3

Thread: [Answers] Variable

  1. #1
    Lianja MVP
    Join Date
    Dec 2012
    Location
    Croatia, Zagreb
    Posts
    1,135

    [Answers] Variable

    Q:
    Is there are way to declare a global variable that is only available to the current prg file and not to other prg files?
    A:
    If it is public, it will be accessible throughout the App and from the Console, so you should be able to check its value or do a LIST or DISPLAY MEMORY to see it.
    Is the file where you added the public declaration a custom library or a separate prg that you have created?
    You could declare the variable under different namespaces for different pages, but that would mean accessing it as namespace.variable, so probably simpler to have different variables if they have different uses.



    Q:
    I need to be able to declare a variable that is visible to all sections within a page
    A:
    Just put it in your namespace in the page init delegate.
    e.g.
    Code:
    namespace PeopleKiosk 
    public MyVar = 0


    Q:
    How do I delete this object that is created?

    Code:
    myform = createobject("form")
    A:
    Code:
    release myform
    or
    Code:
    myform = .f.
    If the form is displayed you need to close() it or release() it.



    variables have to be declared beforehand. This prevents potential spelling errors of variables in your assignments.
    Yes you can use m.var notation, and yes it it slightly faster as fields in the active cursor do not need to be looked up. Lianja uses a hashed block-structured symbol table so lookups are quite fast anyway. It does not do a sequential search.



    Code:
    Lianja.localstorage.setItem( key, value )
    and
    Code:
    Lianja.sessionstorage.setItem( key, value )
    And the corresponding getItem() on these work between desktop and web//mobile



    In v1.2 (should be released today) you also have this that you can use in the Desktop and Web Client to maintain state between Apps.
    Code:
    Lianja.localStorage.setItem(key, value)
    and
    Code:
    value = Lianja.localStorage.getItem(key)
    Also...
    Code:
    Lianja.sessionStorage.setItem(key, value)
    and
    Code:
    value = Lianja.sessionStorage.getItem(key)
    In a point release I will "persist" the localStorage in the desktop client so that it is there next time an app runs.
    You can store e JSON encoded object and use json_decode(value) to restore the state of an object.



    Q:
    Is there a comparable way to define a 2-column array?
    A:



    Alternatively if you know JSON you can create objects and arrays with members that are objects and arrays like this:






    ​All topics in [Answers] alphabetically:http://www.lianja.com/community/show...ll=1#post12352
    Last edited by josipradnik; 2017-02-08 at 02:18.

  2. #2
    Lianja MVP
    Join Date
    Dec 2012
    Location
    Croatia, Zagreb
    Posts
    1,135
    Q:
    I read in the docs that Lianja is loosely typed and that variables with no type in their declaration will be coerced to the type being assigned, so:

    Code:
    myvar = "abc"
    (vartype(myvar) = "C") = .T.
    But this only seems to apply to the assignment, it is not loosely typed when comparing variables ie.

    Code:
    ("1" = 1) = .F.
    In php and javascript "1" = 1 is true and the == operator is used to do strict comparison so "1"==1 is false.
    So if I am correct then what is the == operator for in Lianja because = already seems to do a strict comparison?
    A:
    = and == differ in string comparisons.

    With SET STRCOMPARE OFF (default ON) and SET EXACT OFF (default OFF):

    Code:
    ? "Yvonne" = "Y" // .T.? "Yvonne" == "Y" // .F. not exact match
    ? "Yvonne" = "Y*" // .F. no match
    ? "Yvonne" == "Y*" // .T. pattern match: * = zero or more characters
    ? "Yvonne" == "Y%" // .T. pattern match: % = zero or more characters
    ? "Yvonne" == "Y????e" // .T. pattern match: ? = any one character
    ? "Yvonne" == "_vonne" // .T. pattern match: _ = any one character
    Have a look at etos().
    http://www.lianja.com/doc/index.php/ETOS()

    and

    http://www.lianja.com/doc/index.php/SET_STRICT
    A2:
    the == allows for pattern matching to the tested string, but doesn't allow for cross-type comparisons. You would need to convert the type first.

    For datetime, look at ttoc().

    For numeric and logical you can simply eval().



    Q:
    In my app it would appear that STRICT is OFF (by default) because I get no errors relating to undeclared variables BUT what doesn't make sense then is that the code below fails with a type mismatch (it should auto-convert when strict is off)

    Code:
    s = "a" + 1
    A:
    SET STRICT
    With SET STRICT ON, all variables must be pre-declared.
    By default, SET STRICT is OFF.

    SET STRCONVERT
    If SET STRCONVERT is ON, non-string expressions are automatically converted as they are added to a string.
    If SET STRCONVERT is OFF, expressions must be converted manually using ETOS() or other data conversion functions.
    By default, STRCONVERT is OFF.



    Q;
    I understand the difference between public/private/local and that a private variable is accessible by the routine declaring it and any routines called by that routine. That is why I would expect my msgbox to show "abc" below, not "zzz"

    Code:
    proc page1_section2_field2_click()    
            local a = "abc"
           test()  
            Lianja.showMessage(a)
    endprocproc test()        
            // 'a' will be private here
            a = "zzz"        
    endproc
    'a' in proc 'Test' should only be visible in Test but it still affects the calling function & that seems wrong to me?
    I purposefully used local in the declaration in the click handler because I want that variable to be local only to that routine.
    So what I am demonstrating is that a local variable is being overwritten by a private variable assignment in a 'child' routine - isn't this odd?
    A:
    you used local in the the click event, not private. Change that to private (or don't declare it at all, and it will be private)



    Q:
    If a local variable is declared (with inline assignment) in a loop, then that variable is only assigned to once and will not be re-set while looping.

    This will out put a, a, a:

    Code:
    arr = { "a", "b", "c" }
    foreach arr as s
        local x = s
        Lianja.console(x)
    endfor
    This will out put a, b, c

    Code:
    local x
    arr = { "a", "b", "c" }
    foreach arr as s
        x = s
        Lianja.console(x)
    endfor
    A:
    This is one of the "features" of dynamic scripting in Lianja/VFP.

    If a variable exists it is rescoped to be public, private or local. So redeclaring it in a for loop does not make a lot of sense.
    There was however an issue redeclaring an already existing local variable and assigning a value to it in the same statement and i have corrected this.
    BTW, VFP does not support inline assignments at declaration time nor does it support dynamic array declarations using { ... }. Just so you know.

    A variable declared is loosely typed and can be assigned any data type including arrays and objects.

    Yes all languages are different and often assumptions made are incorrect. Take JavaScript for example. Variable hoisting is rarely understood. Vars that are declared in a loop are hoisted up into the function prologue.
    Rather than wax on about this I will just say its better to declare your variables and their scope outside of loops.
    Myself personally, I recommend declaring them at the top of a proc or function.



    Q:
    because of an external database design. Here is a simplified version of the code that reproduces the problem:

    Code:
    proc page1_section2_field2_click()    
    
            local a = "TableName"
            AddColumn(a)    
    
    endproc
    
    
    proc AddColumn(tableName)
            
            s = "alter table ipranges add column &tableName char(30)"
            &s
            
            //At this point tableName has been overwritten, I'm not sure with what but I suspect it
            //may be an empty string of 30 chrs     
    endproc
    I have tried with other combinations & it happens every time, the issue seems to be passing in the string value "TableName" to a variable with the name 'tableName'. If the value and variable name are different then all is ok.
    A:
    in VFP and Lianja/VFP field names have a higher precedence than variables.
    So if you have a field called name and a variable called name the field will be looked up first.

    It is common practice therefore to name variables prefixed with m_ e.g. m_name so as to avoid name clashes.

    Lianja and VFP are data centric languages.
    A2:
    I use textmerge() (as I've suggested before) in situations like this:

    Code:
    lcDDL = textmerge("alter table ipranges add column <<lcTableName>> char(30)")
    &lcDDL
    Also:

    you can, in VFP and in Lianja, use m. before a variable to enforce the distinction between a variable and a field name. I (and many others from the old school) use l, p and g as a prefix to vars to indicate their scope (local, private, global). This creates another distinction. While I could concoct a context where a collision would occur, I've never had one happen in 25 years of using that naming method.

    I also notice that you used in your function definition:

    Code:
    proc(a)
    While this is allowed, if Lianja follows VFP on this, a will be declared private in that scenario. As a matter of housekeeping, I prefer the parameters to be local (what's said here, stays here). This is accomplished with the the LPARAMETERS statement:

    Code:
    procedure AddColumn
    lParameters tcTableName
    The t before cTableName is a naming convention that indicates "this is a local variable passed to this procedure," thus distinguishing it from a a local variable created in the procedure. As a matter of practice, I do not set t... vars to a different value than passed: makes debugging much easier to know what the value was when passed.
    Parameters in the proc declaration are local as you point out.
    This is not standard VFP, it's another useful extension that reduces typing.



    Q:
    If I use SET STRICT ON then I get this error when calling a proc in a library (works fine when strict is off):

    **** Lianja error ****
    APPDIR() + 'DBFiles'
    ^
    Variable not declared and STRICT is ON
    library code:

    Code:
    jsonFolder = appdir() + 'DBFiles'
    Do I need to declare something else for this to work?
    A:
    With SET STRICT ON you have to declare any variables explicitly. That's what it's all about.

    Code:
    private jsonfolder
    If an error occurs the variables are all released as the stack is unwound. If a variable has been released and you assign to it with SET STRICT ON in effect an error will be reported.



    Q:
    error when calling a routine where that routine declares and assigns a local variable.

    Code:
    proc page1_section2_field2_click() 
            
            messagebox(Test1(), 0)
            
    endproc
    
    
    function Test1() as character
            
            local lcPKString as character = ""
            
            if len(lcPKString) >0
                    lcPKString = lcPKString + ","
            endif
            lcPKString = lcPKString + "a"
            
            return lcPKString
    endproc

    **** Lianja error ****
    lcPKString + ","
    ^
    Data type mismatch

    Changing

    Code:
    local lcPKString as character = ""
    to

    Code:
    local lcPKString as character
    lcPKString = ""
    and it works fine?
    A:
    You can't declare the type and perform an inline assignment.



    ​All topics in [Answers] alphabetically:http://www.lianja.com/community/showthread.php?2717-Answers

  3. #3
    Lianja MVP
    Join Date
    Dec 2012
    Location
    Croatia, Zagreb
    Posts
    1,135
    Q:
    I am trying to upload an image file (http post "multipart/form-data") to a "storeimage.rsp" to process. However, it returns the following error:
    Error message:
    ARRAY reference is out of bounds
    Error line:
    _FILES[0].tmp_nam
    ------------------------------------------------
    How can i read and store the file with the _files[]?

    A:
    The array starts from 1 not 0.
    There is an example included in the distribution in C:\lianja\cloudserver\tenants\public\wwwroot\examp les\example_upload.html which calls C:\lianja\cloudserver\tenants\public\wwwroot\examp les\example_upload.rsp.
    You can run it as http://127.0.0.1:8001/examples/example_upload.html
    Note that example_upload.html references 'http://127.0.0.1/examples/example_upload.rsp' - if you have not enabled port 80 on the Lianja Server (or set up the ISAPI IIS extension), change this to 'http://127.0.0.1:8001/examples/example_upload.rsp'.



    AMEMBERS()
    works with object() also:
    Code:
    lo = object()
    lo.hank = "here"
    lo.yvonne = "over there"
    lo.barry = "way over there"
    ? amembers(awhowhere,lo)
    ? lo
    ? awhowhere
    result:
    3
     Object (refcnt=1)
     (
     [hank] => here
     [yvonne] => over there
     [barry] => way over there
     )
     Array (refcnt=1)
     (
     [1] = HANK
     [2] = YVONNE
     [3] = BARRY
     )
    It also works with the SCATTER MEMO NAME <name> object.



    AMEMBERS() does not work with the UI framework classes
    .



    Q:
    I've a form, with a new container, with a button.
    On the "cick" event, I call a procedure "sp_close_handler"
    Code:
    oContBottom.addObject("sp_close", "commandbutton")
    sp_close.move(1, 1, 60, 20)
    sp_close.text = "Close"
    sp_close.click = sp_close_handler
    
    proc sp_close_handler()
        p_myform.close()
    endproc
    can I send a parameter on the call?
    for example:
    Code:
    oContBottom.addObject("sp_close", "commandbutton")
    sp_close.move(1, 1, 60, 20)
    sp_close.text = "Close"
    sp_close.click = sp_close_handler with "aaa"
    
    proc sp_close_handler(m_text)
        lianja.showmessage(m_text)
        p_myform.close()
    endproc
    naturally, this code not work.. :-)

    A:
    use use a public variable to pass the text.
    If the event to which you you assign sp_close_handler has one or more params, they should be passed to the routine you assign.
    However, the click() event does not have params.
    You could use a public var for this. In Lianja, where we aren't creating large monolithic applications, the usual best practice of "don't use public vars" doesn't really apply. When I have a lot of them, I do place them on an object() when in VFP, or in a dynamic JavaScript array
    VFP
    Code:
    goMyVars = object()
    goMyVars.Phabio = "lasagna lover"
    JavaScript
    Code:
    goMyVars = {};
    goMyVars.Phabio = "lasagna lover";



    All topics in [Answers] alphabetically: https://www.lianja.com/community/sho...ll=1#post13748

    These answers are also systematized on the site "Lianja developer": https://lianjadeveloper.wordpress.co...gory/variable/

Bookmarks

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Journey into the Cloud
Join us