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.
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)
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:
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.
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
Bookmarks