body { margin:0px; background-color:#fff } img { margin:0px; border-style:none } button { margin:0px; border-style:none; padding:0px; background-color:transparent; vertical-align:top } p:first-child { margin-top:0px } table { empty-cells:hide } .f-sp { font-size:1px; visibility:hidden } .f-lp { margin-bottom:0px } .f-x1 { } .f-x2 { } .f-x3 { } a:visited { color:#8b0000; text-decoration:underline } .capsub { color:#808080; font-weight:bold; text-transform:uppercase; letter-spacing:2.4px } .style31 { color:#000 } .code { color:#000; font-family:monospace } .style36 { color:#000; font-weight:bold } .style38 { color:#000; font-style:italic } .style21 { margin-left:0px; margin-right:0px; text-align:center; margin-top:0px; margin-bottom:0.1px } .style52 { color:#000; margin-left:0px; margin-right:0px; text-align:center; margin-top:0px; margin-bottom:0.1px } .style9 { margin-left:0px; margin-right:0px; margin-top:0px; margin-bottom:0.1px } .bold { color:#00f; font-weight:bold } .style39 { margin-left:0px; margin-right:0px; margin-top:0px; margin-bottom:0.1px } .style7 { color:#000; font-style:italic } .rightaligned { margin-left:0px; margin-right:0px; text-align:right; margin-top:0px; margin-bottom:0.1px } .small { color:#000; font-size:90% } .style42 { color:#000; font-weight:bold; font-size:90% } .style33 { color:#808080; font-style:italic; font-size:90% } .style54 { color:#808080; font-style:italic; font-size:90%; margin-left:0px; margin-right:0px; text-align:center; margin-top:0px; margin-bottom:0.1px } .footer { color:#808080; font-size:90% } .FWExtra { } .FWExtra a:link { text-decoration: none; } .FWExtra a:active { text-decoration: none; } .FWExtra a:visited { text-decoration: none; } .FWExtra a:hover { text-decoration: underline; } -->
an introduction to ratcl - Part 4 A few operations are specifically designed to modify a view in place and therefore "alter" its contents: set - set one data item add, insert, delete - row changes addcol, delcol - column changes The example on the right briefly illustrates this. Such changes do not propagate: views previously constructed from R will not change when the above calls are applied to R. To put it another way: Ratcl maintains copy semantics. This avoids surprises when manipulating more substantial datasets. View scopes and lifetimes So far, views have been created with fixed names: R, S, T, U, and V. This can become unwieldy and cause name clashes across different parts of an application. So another way to track a view is via a (local or global) variable or array item, as shown here: The "var" operation ties a view to a variable (or array element) in such a way that the view will be cleaned up when the variable is unset. This is particularly useful with local variables in procs, since it means views created inside a proc will automatically be cleaned up when the proc exits (normally or through an error). By now you must be wondering why one cannot simply use "set" like this: ... unfortunately, the above is a recipe for disaster. Here's the full story: Ratcl needs to manage data as well as Tcl command objects, such as R, S, etc and temporary names such as the above "::ratcl::view::12" for intermediate results. But what if the operations are nested? For example: This takes a view "T", constructs two intermediate views, and ends by displaying the result. This notation is at the heart of being able to construct nested view "expressions" of arbitrary complexity, and is extremely convenient. But how does one get these views to clean up again after use in some cases while staying around in others? one-shot commands The solution adopted in Ratcl is a refinement of Harvey Davies' design of his Tcl-NAP package. It works by constructing new view command objects in such a way that they can only be called once. After one call, views clean up and vanish. As a consquence, the above mapcol/unique/print sequence works exacty as intended: views are created on-the-fly, and cease to exist once called. Two crucial refinements make this practical: First of all, view command objects recognize "as" as a request to disable automatic clean-up. When "as" is called, a temporary view becomes permanent. It will exist until the named command is explicitly deleted. Furthermore, view command objects recognize "var" as a request to transfer the responsibility of automatic cleanup to a named variable (or array item). And that's it. The above logic precisely defines the lifetime of views, and offers solutions for the most common usage scenarios. To summarize:
This has profound implications for how views are used. Failure to play along and get this right will either lead to memory leaks (views/data never being cleaned up) or to command not found errors when a view turns out to no longer exist. This is also why "set name [view ...]" is a bad idea, unless you understand exactly how view reference counts are tracked and know what you are doing. The reward As a consequence of this design, views can now be created and combined at will: And cleanup will be automatic (right after use in the above example). details, details With the above out of the way, the rest is really about details - such as how to get data in and out of Ratcl, and a full overview of all supported view operations. | ||||||