rianmonnahan <
rian.m...@gmail.com> wrote:
> On Friday, March 24, 2017 at 2:49:51 PM UTC+1, Rich wrote:
>> New updated code please....
> clib.tcl modified as per your original suggestions:
>
> #Register the package
> package provide clib 1.0
>
> #Create the namespaces
> namespace eval ::clib {
> namespace export DoTest ReadCSV
> }
>
> #Procedures
> proc ::clib::DoTest {} {
> puts "This is a procedure in clib\n"
> }
>
> proc ::clib::ReadCSV {args} {
> struct::matrix data
> set chan [open [ lindex $args 0 ] ]
> csv::read2matrix $chan data , auto
> close $chan
> set rows [data rows]
> for {set row 0} {$row < $rows} {incr row} {
> puts [data get row $row]
> }
> }
>
> I'll work on the memory leak later.
It's easy:
data destroy
at the end of "ReadCSV" and the matrix is cleaned up.
You'll want to do this anyway, due to the fact that a matrix is a
command. You'll get an error the second time you call ReadCSV for
"data" already exists unless you do clean things up.
> This a contrived example to isolate the problem.
Appreciated - just enough to cause the issue is way easier than having
to wade through pages of non-issue code to find a problem.
Here's what you need to change to both fix the "data, can't find" error
as well as to fix the memory leak:
--- clib.tcl.orig 2017-03-24 13:53:08.927642103 -0400
+++ clib.tcl 2017-03-24 13:53:33.760980424 -0400
@@ -22,9 +22,9 @@
proc ::clib::ReadCSV {args} {
- struct::matrix data
+ set data [struct::matrix data]
set chan [open [ lindex $args 0 ] ]
- csv::read2matrix $chan data , auto
+ csv::read2matrix $chan $data , auto
close $chan
set rows [data rows]
@@ -34,5 +34,5 @@
puts [data get row $row]
}
-
+ $data destroy
}
The reason it was failing for you when you tried to "lib-ize" it is
that struct::matrix creates its commands in the current namespace where
it is executed.
So when you created the "data" matrix, the full command name was
::clib::data.
But, when you passed just "data" over to the CSV module, it was in a
different namespace (the ::csv namespace) and there is no local "data"
in the ::csv namespace, nor is there a global "data" (because
struct::matrix created ::clib::data).
The fix is to capture the return command name from struct::matrix into
a data variable, and then to pass that variables contents into the
csv::read2matrix command. The ::csv::read2matrix can call
"::clib::data" and make use of the matrix.
The destroy at the end just cleans up after itself.