Hawthorne Gray Posted May 11 Share Posted May 11 (edited) I've lately been re-using functions collected in include files as a way to ease the chore of scripting. I'm not a programmer, however, so I run into problems I'm unsure how to fix For example, the following script, 'door_VIP.lsl', is a common door script but written to admit only registered visitors who chose 'blue' as their favorite color when they registered. The script queries the database where a user's info is stored to determine whether they may be allowed through or not by calling on the inserted function: ' checkSTAT();'. It then processes the database response using 'checkRESP(); ': Quote #include "confirmREGX.lsl" default { touch_start(integer total_number) { checkREGX(); } http_response(key request_id, integer status, list metadata, string body) { checkRESP(); if(confirm=="TRUE") { //Do something } else if(confirm=="FALSE") { //Do something else } } } } 'confirmREGX.lsl' Quote string urlregx = "https://xxx/LSL/checkREGX.php"; key http_request_id; key request_id; string confirm; string body; checkREGX() { string avatar_key = llDetectedKey(0); list parameters = [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"]; string http_request_body = "avatar_key=" + llEscapeURL(avatar_key); http_request_id = llHTTPRequest(urlregx, parameters, http_request_body); } checkRESP() { if (request_id == http_request_id) { if (body =="TRUE") { confirm = "TRUE"; } else if (body =="FALSE") { confirm = "FALSE"; } } else { llSay(0, "ERROR: Request IDs do not match."); } } Only this doesn't work properly and results in the error message: ERROR: Request IDs do not match. For some reason, neither of the values assigned to the 'request_id' key or the 'body' string as received by the http_response() function retain their values when processed by the inserted function 'checkRESP()'. After fiddling around for a while I found a work-around. If I assigned those two values to a different pair of variables before calling the 'checkRESP()' function then those values carried over and were processed correctly: Quote http_response(key request_id, integer status, list metadata, string body) { requestID = request_id; resp = body; checkRESP(); if(confirm) { //Do something } else { //Do something else } } with the re-written 'checkRESP()' Quote checkRESP() { if (requestID == http_request_id) { if (resp =="TRUE") { confirm = "TRUE"; } else if (resp =="FALSE") { confirm = "FALSE"; } } else { llSay(0, "ERROR: Request IDs do not match."); } } This worked but left me wondering why is this so? I ended up rewriting checkRESP(); functions like this: Quote checkRESP() { if (requestID == http_request_id) { confirm = resp; } else { llSay(0, "ERROR: Request IDs do not match."); } } I lack the fundamental LSL background tu understanding the underlying principles for why this is so and am hoping someone explain it to me Edited May 11 by Hawthorne Gray simplify examples Link to comment Share on other sites More sharing options...
Frionil Fang Posted May 11 Share Posted May 11 Variable scoping, unrelated to including files from the hard drive. You declared "request_id" as a global variable, and as a parameter to the http_response event. This is allowed, but the event parameter *hides* the global variable instead of writing/reading into/from it: the event's request_id is visible only to that event, and the global variable with the same name is completely inaccessible. Outside the event, like in the checkRESP function, the global variable is seen and the event parameter doesn't exist, much like you couldn't access, say, the event's status integer from the function -- your function is outside the variable scope, and there's no global variable with that name muddying things up by being discoverable. This is why the workaround works, you're actually setting the global variables at that point instead of having them at their blank, default values. Link to comment Share on other sites More sharing options...
Hawthorne Gray Posted May 11 Author Share Posted May 11 4 hours ago, Frionil Fang said: Variable scoping, unrelated to including files from the hard drive. You declared "request_id" as a global variable, and as a parameter to the http_response event. This is allowed, but the event parameter *hides* the global variable instead of writing/reading into/from it: the event's request_id is visible only to that event, and the global variable with the same name is completely inaccessible. Outside the event, like in the checkRESP function, the global variable is seen and the event parameter doesn't exist, much like you couldn't access, say, the event's status integer from the function -- your function is outside the variable scope, and there's no global variable with that name muddying things up by being discoverable. This is why the workaround works, you're actually setting the global variables at that point instead of having them at their blank, default values. Ah, the reason I made 'request_id' and 'body' global variables was because I got "Name not defined within scope" errors on the first go-round. So I made them global which allowed the script to successfully compile but then the "ERROR: Request IDs do not match" messages popped up when the script was run. I'm wondering if this will be a problem in other similar functions like listen()? Link to comment Share on other sites More sharing options...
Quistess Alpha Posted May 11 Share Posted May 11 2 hours ago, Hawthorne Gray said: So I made them global which allowed the script to successfully compile The 'correct' way to fix the problem is to pass the variables as arguments to your function: // Wrong, this doesn't work: foo() { if(myvariable==7) // ERROR: myvariable not declared in scope! //... } //so instead do this: foo(integer myvariable) { if(myvariable==7) //... } default { touch_start(integer number_touched) { foo(number_touched); // now 'number_touched' here turns into 'myvariable' up in the function. } } Link to comment Share on other sites More sharing options...
Hawthorne Gray Posted May 12 Author Share Posted May 12 Wow, I read through this forum a lot but rarely post so, yeh... I'm kinda flattered to have gotten a response from the Quistess Alpha! And! And, one that I can understand and is a promising solution - makes my day - thanks, Quistess. 1 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted May 12 Share Posted May 12 12 minutes ago, Hawthorne Gray said: one that I can understand and is a promising solution Would that I had explained ~why my suggestion would work rather than just giving it straight, but explanation is always harder than giving the solution. https://wiki.secondlife.com/wiki/Category:LSL_User-Defined_Functions is a bit terse, but technically contains almost everything there is to know about user defined functions in LSL. Link to comment Share on other sites More sharing options...
Hawthorne Gray Posted May 12 Author Share Posted May 12 (edited) So, there are two values from the http_response() function which need to be carried over (request_id, body) but I thought to start with just one: request_id. Here's the full script: Quote #include "confirmREGX.lsl" default { touch_start(integer total_number) { checkREGX(); } http_response(key request_id, integer status, list metadata, string body) { resp=body; checkRESP(key request_id); if(confirm=="TRUE") { llSay(0, "Confirmed"); } else if(confirm=="FALSE") { llSay(0, "Dismissed"); } } } ...which throws a syntax error error on line 12: checkRESP(key request_id); So not sure what I've done wrong? Quote checkRESP(key myvariable) { if (myvariable == http_request_id) { confirm = resp; } else { llSay(0, "ERROR: Request IDs do not match."); } } UPDATE: I rewrote checkRESP(key request_id); to checkRESP(equest_id); and the script compiles and functions correctly! Edited May 12 by Hawthorne Gray update Link to comment Share on other sites More sharing options...
Hawthorne Gray Posted May 12 Author Share Posted May 12 (edited) Ok, now the final (as a test script) version works perfectly and means I can use a function that I've written, like 'checkRESP()' as it's meant to be used, a simple, one-line bit of code that can be inserted into a script to perform a routine task and allow me to keep focused on the larger script at hand - no need to worry about where and how and which variables to declare to get a response the required. Quote http_response(key request_id, integer status, list metadata, string body) { checkRESP(request_id, body); if(confirm=="TRUE") { llSay(0, "Confirmed"); } else if(confirm=="FALSE") { llSay(0, "Dismissed"); } } My BIGGEST question is why? I have a basic knowledge of JS, PHP, HTML, CSS, Unix, and MySQL - always enough to get me by. And I've wondered why in LSL you couldn't pass variables through functions. Functions written by a scripter, I mean. I just have never seen it done before. This is a huge step up in knowledge for me, so thanks guys for your responses. Thank You! Edited May 12 by Hawthorne Gray spelling error Link to comment Share on other sites More sharing options...
Quistess Alpha Posted May 12 Share Posted May 12 13 minutes ago, Hawthorne Gray said: I've wondered why in LSL you couldn't pass variables through functions You can even have them return values, though usually only one unless you use a list integer checkRESP(key requestID, string body) { if(/*...*/) // the actual conditions may be more complicated than a simple if block. { return TRUE; // TRUE is an integer constant which is quivalent to 1. }else { return FALSE; } } // . . . http_response(key request_id, integer status, list metadata, string body) { if(checkRESP(request_id,body) ) { llSay(0,"Confirmed."); }else { llSay(0,"Dismissed."); } // if you wanted to be really fancy, the following is roughly equivalent: // llSay(0,llList2String(["Dismissed","Confirmed"],checkRESP(request_id,body))); } Link to comment Share on other sites More sharing options...
Quistess Alpha Posted May 12 Share Posted May 12 29 minutes ago, Hawthorne Gray said: I have a basic knowledge of JS, PHP, HTML, CSS, Unix, and MySQL There are of course many major and minor differences between all languages, but LSL shares a lot of commonality with C. I might be a bit biased because I had dabbled with C before learning LSL, but the C manual I happen to have around is 80~90% 1 to 1 with LSL for the first 3 chapters. Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now