Difference between revisions of "Talk:LlParseString2List"
Fred Gandt (talk | contribs) |
|||
Line 86: | Line 86: | ||
:::Ah ok. I have changed the script above rather than post another. I added explanation of the list return and where llDumpList2String fits in. I did say it was just a start. I also mentioned that spacers needed explanation. I think rather than saying "this bad" it would help to say what would constitute good use of this function. If not for string replacement...what is a "good" use? -- '''[[User:Fred_Gandt|Fred Gandt]]''' <sup><small>([[User talk:Fred_Gandt|talk]]|[[Special:Contributions/Fred_Gandt|contribs]])</small></sup> 11:11, 30 April 2010 (UTC) | :::Ah ok. I have changed the script above rather than post another. I added explanation of the list return and where llDumpList2String fits in. I did say it was just a start. I also mentioned that spacers needed explanation. I think rather than saying "this bad" it would help to say what would constitute good use of this function. If not for string replacement...what is a "good" use? -- '''[[User:Fred_Gandt|Fred Gandt]]''' <sup><small>([[User talk:Fred_Gandt|talk]]|[[Special:Contributions/Fred_Gandt|contribs]])</small></sup> 11:11, 30 April 2010 (UTC) | ||
:::: <.< I may have been a bit harsh. I am sorry. -- '''[[User:Strife_Onizuka|Strife]]''' <sup><small>([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])</small></sup> 12:41, 30 April 2010 (UTC) | |||
Here is how the function basically works: (llParseString2List is a bit more complicated) | |||
<lsl>//rough pseudocode for llParseString* functions | |||
//I've used some convenient fake functions to make the implementation easier to read. | |||
//They are for convenience sake only, you would never implement it this way. | |||
list llParseString2List(string str, list separators, list spacers) | |||
{ | |||
list out = []; | |||
string buffer = str; | |||
while(buffer) | |||
{ | |||
integer index = IndexOfFirstListItemInString(buffer, spacers + separators); | |||
if(index == -1) | |||
return out + buffer; | |||
else if(IsIndexInList(buffer, index, separators)) | |||
{ | |||
if(index) | |||
out += llDeleteSubString(buffer, index, -1); | |||
buffer = llDeleteSubString(buffer, 0, index + LengthOfListItemInStringAt(buffer, separators, index) - 1); | |||
} | |||
else //it's a spacer | |||
{ | |||
if(index) | |||
out += llDeleteSubString(buffer, index, -1); | |||
out += ListItemInStringAt(buffer, spacer, index); | |||
buffer = llDeleteSubString(buffer, 0, index + LengthOfListItemInStringAt(buffer, spacer, index) - 1); | |||
} | |||
} | |||
return out; | |||
}</lsl> | |||
For a complete LSL implementation, take a look at [[ParseString2List]]. It's very clever. -- '''[[User:Strife_Onizuka|Strife]]''' <sup><small>([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])</small></sup> 12:41, 30 April 2010 (UTC) |
Revision as of 04:41, 30 April 2010
- Is there a limit to the number of items that this function will parse into a list? —The preceding unsigned comment was added by Bobby Fairweather
- Yes there is a limit, the amount of free memory the script has. —The preceding unsigned comment was added by Strife Onizuka
A replacement of the examples for llParseString2List and llParseStringKeepNulls.
I feel that the present examples are too confusing to read and don't really help teach what the functions do (I find the repeated <<>>><<<>><<> totally baffling). I tried to write an example myself but think it fails to show the functions at their best (it just sucks to be frank) but is easier to read and IMO clearer to understand what these functions do. Could we pull together and sort something out? -- Fred Gandt (talk|contribs) 01:36, 30 April 2010 (UTC)
- Example script stage 2 -
<lsl>// IMPORTANT!!
// This code is here to aid an ongoing discussion and should not be used as an example of good code.
// IMPORTANT!!
default {
state_entry() { // We have a string of text that we want to adapt. string source = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?"; list words = llParseString2List(source, ["much"], []); // This divides the string source into two elements at the point it finds "much" and removes "much" // This list is returned - ["How ", " wood would a woodchuck chuck if a woodchuck could chuck wood?"] // We can then feed the list to llDumpList2String to join the list elements using something new as glue. source = llDumpList2String(words, "many"); // Our source is now "How many wood would a woodchuck chuck if a woodchuck could chuck wood?" // However, this can be simplified by feeding the return of llParseString2List directly into // llDumpList2String. Like so - source = llDumpList2String(llParseString2List(source, ["much"], []), "many"); // That method makes the need for list words redundant. // We remove all instances of "chuck" and replace with "rez". source = llDumpList2String(llParseString2List(source, ["chuck"], []), "rez"); // Our source is now "How many wood would a woodrez rez if a woodrez could rez wood?" // We remove all instances of "wood" and replace with "prims". source = llDumpList2String(llParseString2List(source, ["wood"], []), "prims"); // Our source is now "How many prims would a primsrez rez if a primsrez could rez prims?" // We remove all instances of "primsrez" and replace with "primrez". source = llDumpList2String(llParseString2List(source, ["primsrez"], []), "primrez"); // Our source is now "How many prims would a primrez rez if a primrez could rez prims?" llOwnerSay(source); // Say the result to the owner. // There is an issue though... source = "Peter Piper picked a peck of pickled pepper."; llOwnerSay(llDumpList2String(llParseString2List(source, ["P", "p"], []), "m")); //Returns "eter mimer micked a meck of mickled memer." // Notice that ALL the p's are gone and llDumpList2String adds "m" only where the split ocurred. // We can then use llParseStringKeepNulls instead. llOwnerSay(llDumpList2String(llParseStringKeepNulls(source, ["P", "p"], []), "m")); //Returns "meter mimer micked a meck of mickled memmer." }
}</lsl>
- I like the pepper/ memer example
- http://en.wikipedia.org/wiki/Comma-separated_values#Example is an instance of people solving a puzzle like this before us ...
- -- Ppaatt Lynagh 01:49, 30 April 2010 (UTC)
- Agreed. I think the value of llParseStringKeepNulls is far simpler to express when an understanding of llParseString2List is already established. I am way too tired to tackle this further right now but I am inspired by your interest Ppaatt. I hope between us (the community) we can create a couple of examples that really show off these functions. For example - What exactly is the use of the second list param (spacers)? -- Fred Gandt (talk|contribs) 02:23, 30 April 2010 (UTC)
- I don't agree with the proposed example. Sure it shows you one use of the function but it doesn't give a the user an understanding of what llParseString2List is doing. While it is documented, the documentation doesn't actually talk about how it is performing what it is doing. From this example, you cannot really tell where the llDumpList2String functionality begins and the llParseString(KeepNulls|2List) functionality ends. It isn't plain to the user from this example that llParseString2List is returning a list or what the list looks like; it could be returning a black box for all the user knows. The way it is being used in this examples is a simple text replace and it's not even a memory efficient way of doing text replace. On the efficiency front, I'm inclined to say this is a Bad example, sure it works great on short strings, but give it a string that is 1024 or longer characters and have it replace every other character and you may just hit the memory limits. Sure the alternative is slow but it doesn't use six times the memory. So to some it up: It doesn't actually demonstrate the full use of this function (hello it doesn't even use spacers) and the example usage it provides is hazardous. I do however acknowledge that the current example is less than perfect and needs improvement. -- Strife (talk|contribs) 05:01, 30 April 2010 (UTC)
- I don't want to be providing hazardous code in the examples as people will copy it. It will end up being used in products; in vendors. People will think that because it's in an example that it is good coding practice; that it has been vetted. This example has the potential to be a DoS attack vector: If this code is fed third party text the third party could crash the script. It would be pretty short sighted of us to provide a DoS attack vector in an example. If it ever became public that it was our fault for providing such an example it would damage the image of the LSL Portal. -- Strife (talk|contribs) 05:17, 30 April 2010 (UTC)
- Number of years ago I tried to use this method for text replacement but the stack would occasionally collide with the heap and crash the script. It was suffice it to say, annoying. Ended up going back to using my own text replacement function (an early version of it can be found here near the bottom of the page). -- Strife (talk|contribs) 05:26, 30 April 2010 (UTC)
- Ah ok. I have changed the script above rather than post another. I added explanation of the list return and where llDumpList2String fits in. I did say it was just a start. I also mentioned that spacers needed explanation. I think rather than saying "this bad" it would help to say what would constitute good use of this function. If not for string replacement...what is a "good" use? -- Fred Gandt (talk|contribs) 11:11, 30 April 2010 (UTC)
Here is how the function basically works: (llParseString2List is a bit more complicated) <lsl>//rough pseudocode for llParseString* functions //I've used some convenient fake functions to make the implementation easier to read. //They are for convenience sake only, you would never implement it this way. list llParseString2List(string str, list separators, list spacers) {
list out = []; string buffer = str; while(buffer) { integer index = IndexOfFirstListItemInString(buffer, spacers + separators); if(index == -1) return out + buffer; else if(IsIndexInList(buffer, index, separators)) { if(index) out += llDeleteSubString(buffer, index, -1); buffer = llDeleteSubString(buffer, 0, index + LengthOfListItemInStringAt(buffer, separators, index) - 1); } else //it's a spacer { if(index) out += llDeleteSubString(buffer, index, -1); out += ListItemInStringAt(buffer, spacer, index); buffer = llDeleteSubString(buffer, 0, index + LengthOfListItemInStringAt(buffer, spacer, index) - 1); } } return out;
}</lsl> For a complete LSL implementation, take a look at ParseString2List. It's very clever. -- Strife (talk|contribs) 12:41, 30 April 2010 (UTC)