Editing
Module:Buffer/doc
(section)
From Thetacola Wiki
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Usage== {{anchor|module|initialize}} ===require'Module:Buffer'=== {{luaself|Buffer|\|require'Module:***'|subpage= |args=...|args2=_G, name, ...}} Creates a new Module:Buffer object when the module returned by {{luaref|require||y}} is called as a function{{--}}i.e., there is no 'main'. Because <span title='i.e. never accept arguments'>{{luaref|mw.html:done|public methods with useless parenthesis|y}}</span> are a [[pet peeve]] of this developer, this forwards arguments to {{luaself|:_}}; if that op is not desired, you may chain a Buffer object function directly to the module and the self-action will be redirected to a new Buffer object{{--}}i.e [[#Buffer:_inHTML|{{code|lang=lua|require'Module:Buffer':_inHTML'table'}}]] is equivalent to {{code|lang=lua|require'Module:Buffer'():_inHTML'table'}}.<ref group="note">For your convenience, the self operator {{code|:}} and {{code|.}} are interchangeable when used on the Module directly, though the self-op is required for nearly all other interactions with objects created by the Module.</ref> The global variable {{luaref|_G}} is "magic" when passed as the first arg. Such enables the [[#Global functions|global functions]] and, if followed by a <code>name</code> string, will declare the new Buffer with that name in the global scope. If the argument following ''name'' is a table with no metatable, it and any other {{luaref|varargs||y}} are forwarded to {{luaself|:_all}}; otherwise, as long as the first vararg is not nil or false, this passes them to {{luaself|:_}}.<ref group="note">Passing arguments after ''name'' is primary used when {{luaself|:_in}} is indirectly called by {{luaself|:_all}} or {{luaself|pre=Element-|:_add}}. For example:<br /> {{code|1=require'Module:Buffer'(_G,'arg'):_all({'arg',arg and {' was saved:' ,_in={_G, 't', ' awesome'}{{))}}, true):_(t and {t(), t..'r', t..'st'})|lang=lua}}<br /> produces: {{code|arg was saved: awesome awesomer awesomest|lang=lua}}</ref> The _G passed may also gain a __call {{luaref|Metatables|metamethod|y}} (details at [[#G object|_G object]]). {{anchor|recycling}} As a final note, if you {{luaref|require|plain=y}} text from a module which returns a Buffer object, it may be more efficient to create a new Buffer via chaining {{luaself|Buffer|:_in|:_in|args=()}} after a require statement for the other module and use {{luaself|:_parent|args=()}} at the point where you would append the required text. (Best add {{code|lang=lua|1=--:_in == indirect require Module:Buffer}} so future editors won't hunt for {{code|lang=lua|function ...:_in}} at the other module) ===Basic functions=== {{anchor|Buffer}} ====Buffer object==== {{luaself|\|args=sep, i, j}} {{hatnote|See also {{luaself|:_str|plain=y}} for advanced string conversion.}} Get a Buffer as a {{luaref|string||y}} via a function call on the Buffer ''object'' (as opposed to [[#require'Module:Buffer'|a call on the ''module'']]). This is basically shorthand for {{luaref|table.concat|args=Buffer, sep, i, j}}, or, with no args, {{luaref|tostring|args=Buffer}}. However, if this Buffer is in [[#raw|raw mode]]<ref group="note" name="raw" /> or contains at least one {{luaref|sequence|non-sequential|y}} index, this reconstructs the Buffer by creating a new table, coercing it contents to strings and appending them sequentially to the temporary "buffer" via <code>new-{{luaself|:_all|plain=yes|args=Buffer}}</code> (or a similar process). Unconventionally, any {{luaref|string||y}}-type position passed as <code>i</code> or <code>j</code> are treated as ''relative to length''; that is, {{luaself|\|args='-', -1, '-3'}} is equivalent to {{luaself|\|args='-', -1, #Buffer - 3}} (which obviates the need to {{luaref|Local variable declarations|declare a local|y}} ''Buffer'' just to use the {{luaref|Length operator|length operator|y}}). Moreover, unlike table.concat, this automatically adjusts numerical<ref group="note">Later sections may describe values as being ''numerical'' or ''numeric''. Though perfect synonyms in normal usage, these adjectives are not interchangeable here. For the purposes of documenting Module:Buffer, ''numerical'' includes both actual number values and string values which {{luaref|tonumber|args=value}} does not return nil (and often involves Buffer-style length relativity); ''numeric'' describes values of number type only.</ref> positions to be within the range of the lowest and greatest indicies. Note you may append a Buffer object without tostring coercion to an {{luaref|HTML library|mw.html|y}} object via {{luaref|mw.html:node}} (though not mw.html:wikitext because of type checking). =====Buffer.last_concat===== When strung without a ([[#valid|valid]]) <code>sep</code>, the result is cached at <code>Buffer.last_concat</code>. Until purged, future calls to return that Buffer as a string will return this index instead.<ref group="note">Using {{luaself|:_var|plain=y}} prevents future caching on all Buffers, though Buffers which already unmodified Buffers will continue to return their cached version</ref> This should clear automatically whenever a Buffer object function changes the contents of a Buffer. You may manually purge the cache by setting this key to nil, as well as by passing nothing to {{luaself|:_cc|args=()}}. ====Buffer:_==== {{luaself|:_|args='string'|args2=value, pos, raw|args3=value, raw}} {{hatnote|See also {{luaself|:stream|plain=y}} for a faster, simpler version of this op.}} Appends a value to the Buffer. In rough terms, {{code|lang=lua|Buffer:_'string1':_'string2'}} is the same as {{code|lang=lua|Buffer {{=}} Buffer..'string1'..'string2'}}. (It may help to imagine {{code|:_}} as a {{code|..}} that has stood up and is now casting a shadow.) {{anchor|valid|invalid|no-op}} If passed an ''invalid'' {{code|value}} listed below, this is a no-op: * {{luaref|boolean||y}} * {{luaref|nil||y}} * empty {{luaref|string||y}}, or any table such that {{luaref|tostring|args=table}} returns an empty string (or nil/false) * {{luaref|table||y}} without a __tostring metamethod and which {{code|table[1]|lang=lua}} is nil or false A table with no __tostring will pass through {{luaref|table.concat}} before insertion. An {{luaref|error|plain=y}} may be thrown if the table would cause table.concat to error. (Use {{luaself|:_all}} instead for such tables.) When passed {{code|pos}} of type {{luaref|number|plain=y}}, the argument is identical to ''pos'' for {{luaref|table.insert|args=table, pos, value}}. In fact, assuming a [[#valid|valid value]], {{luaself|:_|args='string', 1}} is exactly the same as {{luaref|table.insert|args=Buffer, 1, 'string'}}. Just like with the position arguments of [[#Buffer|Buffer()]], any ''pos'' of type {{luaref|string|plain=y}} would be treated as relative to length. {{anchor|raw}} Set {{code|raw}} to true to force append a ''value'' without tostring coercion, including [[#no-op|invalid]] values. If given only two (non-self) arguments with the second being a boolean, then the second is read as ''raw'' instead. ====Buffer:_nil==== {{luaself|:_nil|args=pos, replacement|args2=replacement}} Removes the value buffered at {{code|pos}}. As with {{luaself|:_}}, a string ''pos'' string is treated as {{code|lang=lua|#Buffer + pos}}. If a non-boolean {{code|replacement}} is provided, then it will replace the value indexed at ''pos''. Passing a boolean as the second argument is a no-op. When ''replacement'' is nil, the op is basically {{luaref|table.remove|args=Buffer, pos}}. As with the positional arguments of other Buffer methods, any numerical string ''pos'' is added to length, such that {{luaself|:_nil'0'}} removes the last item. Note the only type check on replacement is a direct comparison to both booleans (nil is implied). Any other type, including strings, sets the Buffer to [[#raw|raw mode]]. A ''pos'' that is omitted, nil, or false has the same effect as though <code>'0'</code> (or {{luaself|pre=#|\}}) were passed. Given only one non-numerical argument which evaluates true but {{luaref|tonumber||y}} would return it as nil, this treats it as though it were passed as the second. If passed a non-numerical ''pos'' with any other argument, including nil, this is effectively a no op (though may still purge the [[#Buffer.last_concat|cache]]). ====Buffer:_all==== {{luaself|:_all|args={ value, ... }|args2={ ..., value = pos, functionName = args, ... }, nanKeys}} Takes a table {{code|value}}, iterates through all number keys {{luaref|table.sort|in order|plain=yes}}, appending each [[#valid|valid]] value to the end of the Buffer. In contrast to {{luaref|ipairs}}, this starts at the most negative key (down to {{luaref|math.huge|-inf|y}}) and ends at the most positive index, continuing through any nil keys and includes [[Double-precision floating-point format|non-integer number keys]]. A table ''value'' that has no metatable will have its contents iterated by this function before moving on to the next value. All other data types are processed by {{luaself|:_}}. {{anchor|nanKeys}} By default, this ignores non-number keys unless {{code|nanKeys}} evaluates true. If so, non-number keys are processed after number keys. Keep in mind such keys are iterated in {{luaref|next|no particular|y}} order, though an order may be imposed by wrapping each pair in a table indexed at a number key. If given a <code>''value'' = ''pos''</code> pair, defined as a number or number string indexed at a non-number key, then they will be passed as the {{code|value}} and {{code|pos}} arguments for {{luaself|:_|plain=y}}. Thus, :{{luaself|:_all|args=({1,2,3,'... done',[3.5]=variable and 4 or {four='1',zero=1{{))}},true)}} produces the same result as: :{| |{{#tag:syntaxhighlight|Buffer:_(1):_(2):_(3) if variable then Buffer:_(4) else Buffer:_'four':_('zero',1)--vs :_all{four='1',zero=1}; less redundant would be end -- :_all{'four',zero=1}, but that doesn't demo string numbers Buffer:_'... done' --returns "1234... done" if variable evaluates true or "zero123four... done" if false|lang=lua}} |} If a non-number key points to a value that cannot be coerced into a {{luaref|tonumber|coerced into a number|y}} then the pair may be treated as <code>''functionName'' = ''args''</code>, when ''functionName'' matches a Buffer object function and ''args'' is not boolean. If ''args'' is such that {{code|value[1]|lang=lua}} evaluates true, then this will pass the return of {{luaref|unpack|args=value, 1, table.maxn(value)}} to the named function; otherwise, the value is passed as is.<ref group="note">In other words, if ''args'' is a string or a table without [1] set, it will be passed as the only argument. Further note it is not possible to pass a <code>''functionName'' = ''args''</code> pair where ''args'' is numerical since such would be read as <code>''value'' = ''pos''</code>. Finally, passing a function type as ''args'' will throw an error message.</ref> ====Buffer:_in==== {{luaself|:_in|args=...|args2=_G, name, save, ...}} Passes any arguments to [[#require'Module:Buffer'|Module:Buffer]] to create a new Buffer object, sets an external reference to the parent Buffer and returns the child.<ref group='note' name='in-dependents'>There is no 'getChild' method. If a child needed after returning to the parent, set it {{luaref|Local_variable_declarations|locally|y}} or use {{luaself|:_G}} prior to returning or it may become irretrievable. (No, {{u|Codehydro}} did not get lazy. Rather, this allows {{luaref|Garbage collection|garbage collection|y}} on children with no further purpose.)</ref> This does <u>not</u> append the child to the parent. (See {{luaself|:_out|plain=y}}) Also, be aware that Buffer parent references are {{luaref|weak tables|weak|y}}. Thus, if you were to (re-)set a local variable that is currently set to the parent, such could trigger immediate garbage collection on the parent. ====Buffer:_out==== {{luaself|:_out|args=sep|args2=ops, sep{{ndash}}list, { default{{ndash}}sep, ..., [#] = sep }|args3=0, sep}} [[#Buffer object|Joins a Buffer]] with {{code|sep}} and appends result to its parent, which is returned. If no parent is found, this is a no-op and returns the same Buffer. When given two or more arguments, this reads the first as {{code|ops}}{{--}}the number of :_out() operations to perform.<ref group="note">The first arg is not type checked but read as ''ops'' only when multiple args are present (or if it is the number 0); i.e., <code>Buffer:_out(2)</code> uses <code>2</code> as a separator. To append to the ''N''th ancestor with no separator, use <code>Buffer:_outs(''N'', nil)</code>.</ref> This applies the first ''sep'' in {{code|sep-list}} for the current Buffer, the second for its parent, the third for its grandparent, and so on. If the last item is a {{luaref|table||y}}, then any ''nil'' in ''sep-list'' default to <code>''table''[1]</code>; any ''false'' mean "no-sep".<ref group="note">Empty strings would produce the same output as false, however, Lua string literals create objects that take up memory until garbage collected.</ref> The table may be the second arg (i.e. ''sep-list'' may be omitted). If it has other keys, then ''table[n]'' would apply instead of ''table[1]'', making these synonymous:<br /> {{luaself|:_out|args=4, nil, nil, nil, ' and ', {', '} }} and {{luaself|:_out|args=4, {', ', [4] = ' and '} }}. The number {{code|lang=lua|0}} is "magic" when passed as the first arg (even by itself), joining and appending to the same Buffer ''after'' it has been {{luaself|Buffer|:_cc|emptied|y}}. This is the only method by which a Buffer in [[#raw|raw mode]] may lose that status. Parent references are preserved. ====Buffer:_str==== {{luaself|:_str|args=sep|args2=ops, sep{{ndash}}list, { default{{ndash}}sep, ..., [#] = sep } }} Joins a Buffer with {{code|sep}} and returns the string. This uses the same helper method as {{luaself|:_out}} to handle multiple arguments, with which, if provided, this creates a new temporary Buffer to which this appends the results of the number of generations specified by <code>ops</code>, with each ancestor in front of its descendants. This then performs one additional concat op using the ''sep'' at {{code|ops + 1|lang=lua}} and returns the result. If a parent-less Buffer is reached before ''ops'', then the sep that follows its op number will separate the generations. When no [[#valid|valid]] ''sep'' is given, this returns a string identical to what would append to the next ancestor, if those arguments were passed to Buffer:_out instead and one additional :_out() op performed. However, because this does not actually append child Buffers to their parent, the result may differ where this would insert the sep at ''ops + 1'' and Buffer:_out would place the parent's sep between it and its child instead. ====Buffer:_cc==== {{luaself|:_cc|args=clear, copy, meta|args2=0, true}} Nils all keys of the table referenced by {{code|clear}} and unsets its metatable. If ''clear'' evaluates false, this simply purges the cache at {{luaself|.last_concat}}. If given a table to {{code|copy}}, this will duplicate all key-value pairs of ''copy'' into ''clear'', cloning any table value recursively via {{code|lang=lua|Buffer:_cc(0, value)}}. This returns the Buffer unless passed the number {{code|lang=lua|0}} as ''clear'', which causes this to create a new table and return that instead. Passing {{code|lang=lua|true}} as ''copy'' is equivalent to passing the Buffer itself. If ''copy'' is not a table, then it will be set as the first item in ''clear'' as long as it is not ''false''. While this may resemble {{luaref|mw.clone}}, there are several differences, namely that this: * Gives ''clear'' the same metatable as ''copy'' (or sets <code>meta</code>, if given) as opposed to a "clone" of the metatable. * Conserves {{luaref|Length operator|Length|y}} attribute (though empty strings may replace some nil keys<ref group="note">For example, given {{code|lang=lua|{nil, 'string'} }} as ''copy'', {{code|lang=lua|Buffer:_cc(clear, copy)}} makes {{code|lang=lua|#clear}} equal <code>2</code>, whereas {{code|lang=lua|#mw.clone{nil, 'string'} }} equals <code>0</code> (as of March 2015). This replicates length by filling clear halfway to the length of copy (the minimum needed to 'trick' Lua) and then setting nil every key that would not trigger recalculation. As a result, keys that would resize ''clear'' when set nil are left as empty strings. Such should be fairly rare; given tables representing every possible way to position a single nil key for all lengths between 2 and 32 (inclusive), only 8.39 percent of such tables would have its nil copied as an empty string instead.Also note that tables returned from {{code|lang=lua|Buffer:_(0, copy)}} have length declared on creation instead, and thus won't have extra strings attached. The odds can be estimated using <math>y {{=}} 0.5 / \sqrt{x}</math>, where <math>y</math> is the upper limit that an arbitrary nil key from ''copy'' of length ranging from 1 to <math>x</math> is imaged as an empty string.</ref>) * {{luaref|Rawset||y}}s values and iterates without invoking any __pairs {{luaref|Metatables|metamethod|y}}. * Includes Buffer parent and [[#raw|raw]] attributes (stored externally) To obtain the key-value pairs left as empty strings in the previous copy op in a table, simply call this again such with value such that <code>rawequal(clear, copy)</code> is true; call :getParent() on this table returns ''clear'' (useful after leeaving the local scope which referenced ''clear''). ====Buffer:_parent==== {{luaself|:_parent|args=sep|args2=ops, sep{{ndash}}list, { default{{ndash}}sep, ..., [#] = sep } }} {{hatnote|To skip generations without breaking the Buffer chain, see [[#global functions]].}} Resembling the reverse of {{luaself|:_out}}, this calls {{luaself|:_str}} on the Buffer's parent with the arguments given and appends the strung ancestor(s) to the current Buffer, which is returned. The parent is unaffected by this operation and may still be retrieved via {{luaself|:_out}} or re-appended again with this function. ====Buffer:getParent==== {{luaself|:getParent|args=value|args2=functionName, ...}} {{hatnote|Note that there is no 'getChild' method<ref group='note' name='in-dependents'/>}} Returns parent Buffer, or, if none exists, creates a new Buffer and returns it as the adopted parent. As with {{luaself|:_in}}, this does not automatically append the adoptive child to the new parent. Pass a non-false <code>value</code> and this performs an op on the parent object. If passed anything other than ''value'' (including nil), this requires that ''value'' names a function available to the parent object, which this calls and forwards the additional {{luaself|varargs|plain=yes}}. Pass only a table ''value'' which has no metatable and this forwards ''value'' to the parent which calls {{luaself|:_all|args=value}}. Given only a string starting with {{code|_}} and naming a parent function, this calls it on the parent without arguments. Any other [[#valid|valid]] singular argument [[#Buffer:|appends]] to the end of the parent Buffer.<ref group="note">In other words, {{luaself|:getParent|args='_nil'}} is shorthand for {{luaself|:getParent|args=():_nil()}}, however, {{luaself|:getParent|args='match'}} simply appends "match" to the parent. Note that you may still call {{luaself|Buffer|library|***:match|args=pattern}} on a parent via {{luaself|:getParent|args='match', pattern}}.</ref> ====Buffer:killParent==== {{luaself|:killParent|args=...}} Unsets Buffer parent reference. If passed any args, they are forwarded to the current parent, if one exists, via Buffer:getParent as a "parting gift". In either case, returns the current Buffer. This is not necessary for {{luaref|garbage collection||y}} since Buffer parent references are weak. Rather, use this when it is desirable to assign a new parent via Buffer:getParent or, for example, to prevent the inclusion of an ancestor when passing {{luaref|math.huge}} as ''ops'' for functions such as {{luaself|:_out|plain=y}} (more useful when [[#recycling|recycling Module:Buffer]] from another Module). ===Stream mode=== ====Buffer:stream==== {{luaself|:stream|args=...}} Switches a Buffer to [[#Stream-Buffer|stream mode]]. While streaming, the __call metamethod will append values to the end of the Buffer instead of the [[#Buffer object|usual op]]. Aside from that, there is only one other function: {{luaself|pre=Stream{{ndash}}|:each}}. Any args passed to Buffer:stream are forwarded to that function for a reason that should be evident when you finish reading this very short section. No special action is needed to exit this mode. The normal call to string op is restored upon the use of any regular Buffer function or any operation which coerces the Buffer into a string (e.g. the <code>..</code> operator). {{anchor|Stream-Buffer}} ====Stream-Buffer object==== {{luaself|pre=Stream-|\|args='string'|args2={concat{{ndash}}list}|args3=(var)}}{{anchor|streaming|calling a Buffer:stream}} Stream-Buffer objects accept only one argument which they append if [[#valid|valid]]. That is, the op is a streamlined version of {{luaself|:_}} sans the ''pos'' and ''raw'' args. This also exploits {{luaref|named arguments|the syntactic sugar of function calls|y}} to append a series of string literals (and tables) with nothing between them (or only {{luaref|Character class|ASCII space chars|y}} if desired). For example, both A and B will produce identical strings: :{| |{{#tag:syntaxhighlight|local A = require'Module:Buffer':stream'A string of text may flow'<nowiki />'with nothing between each string' 'or perhaps only a space' 'or even tab and line-break characters'<nowiki />'and continue to append individually'<nowiki />'for use with a joiner' local B = require'Module:Buffer':_'A string of text may flow':_'with nothing between each string' :_ 'or perhaps only a space' :_'or even tab and line-break characters':_'and continue to append individually':_'for use with a joiner' mw.log(A==B, A:_str' ') true A string of text may flow with nothing between each string or perhaps only a space or even tab and line-break characters and continue to append individually for use with a joiner |lang=lua}} |} ====Stream-Buffer:each==== {{luaself|pre=Stream-|:each|args=...}} Appends an undetermined number of [[#valid|valid]] values to the Buffer object.<ref group="note">This is no different than calling the Stream-Buffer object directly with each item in the {{luaref|expression list}}; however, after noting how numbers and variables (too shy to [[skinny dip]] without parenthesis) could look rather odd swimming fully clothed in a stream of naked strings, this was made for those whose aesthetics prefer {{luaself|pre=Stream-|:each|args=('A',arg,'B',arg2)}} over {{code|lang=lua|Stream{{ndash}}Buffer'A'(arg)'B'(arg2)}}.</ref> If the above line gives you [[DΓ©jΓ vu]], that is because it is drawn from {{luaref|mw.html:wikitext|plain=y}}. However, unlike mw.html:wikitext, this does ''not'' stop at the first ''nil'' value.<ref group="note">If you want something like {{code|lang=lua|:wikitext('string1', varName, 'string2')}} such that ''varName'' is shorthand for an {{code|lang=lua|if}} statement that appends ''varName'' and 'string2' when the former is not nil, use {{code|lang=lua|:each('string1', {varName, 'string2'})}} instead.</ref>
Summary:
Please note that all contributions to Thetacola Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Project:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Page actions
Module
Discussion
Read
Edit source
History
Page actions
Module
Discussion
More
Tools
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Search
Tools
What links here
Related changes
Special pages
Page information