• I can't parray in a text widget

    From Luc@21:1/5 to All on Wed Nov 16 11:42:56 2022
    I am really struggling with this:

    --------------------
    package require Tk

    text .t -width 40 -height 6 -font "FreeSans 18"
    pack .t

    array set file_1 {name file1 date today size 100k}
    array set file_2 {name file2 date today size 200k}
    array set file_3 {name file3 date today size 300k}

    proc p.printfiles argNumber {
    .t delete 1.0 end
    .t insert end ::file_$argNumber
    .t insert end "\n"
    .t insert end "parray: [parray ::file_$argNumber]"
    .t insert end "[set ::file_[set argNumber](size)]"
    parray ::file_$argNumber
    }

    p.printfiles 2
    --------------------

    Result:
    ::file_2
    argNumber
    parray:
    200k

    I've tried all kinds of formats and escaping and can't get the code to
    insert the output of [parray] into the text widget.


    And the plot thickens. If I include [info vars] in those insert lines, the
    only var it finds is argNumber. What about the global vars? Where are they?

    Maybe that is why it can't print [parray]?

    No, that is not the reason because

    1) the parray line at the end works fine in stdout.

    2) this line works as expected:

    .t insert end "[set ::file_[set argNumber](size)]"

    What am I doing wrong?

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From [email protected]@21:1/5 to All on Wed Nov 16 15:11:35 2022
    From: Luc <[email protected]>
    Date: Wed Nov 16 14:42:56 GMT 2022
    Subject: I can't parray in a text widget


    parray prints the array (like puts). It returns an empty string result.
    Try:

    array set aa {a 1 b 2 c 3}
    set rr [parray aa]

    << see array printed on console>>

    set rr

    << see empty string>>

    Dave B

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Helmut Giese on Wed Nov 16 12:54:30 2022
    On Wed, 16 Nov 2022 16:29:13 +0100, Helmut Giese wrote:

    Hi Luc,
    no, you cannot 'parray into a text widget':
    'parray' writes to stdout and a text widget wants
    '$t insert <index where> <text>'.
    I think the simplest solution is:
    - look into the file 'parray.tcl' (on my installation it is located in
    <path to my installation>/lib/tcl8.6
    - rename the parray function, add another parameter to it
    and replace the line 'puts stdout ...' with '$t insert ...'

    HTH
    Helmut


    OK, I had a wrong understanding of parray.

    Thank you for the clarifications.

    I am doing

    foreach i [array names ::file_$argNumber] {
    .t insert end "[set ::file_[set argNumber]($i)]\n"
    }

    A little ugly and hard to read, but it works.


    Thank you.

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Helmut Giese@21:1/5 to All on Wed Nov 16 16:29:13 2022
    Hi Luc,
    no, you cannot 'parray into a text widget':
    'parray' writes to stdout and a text widget wants
    '$t insert <index where> <text>'.
    I think the simplest solution is:
    - look into the file 'parray.tcl' (on my installation it is located in
    <path to my installation>/lib/tcl8.6
    - rename the parray function, add another parameter to it
    and replace the line 'puts stdout ...' with '$t insert ...'

    HTH
    Helmut

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Wed Nov 16 17:30:56 2022
    Am 16.11.22 um 16:54 schrieb Luc:
    Thank you for the clarifications.

    I am doing

    foreach i [array names ::file_$argNumber] {
    .t insert end "[set ::file_[set argNumber]($i)]\n"
    }

    A little ugly and hard to read, but it works.

    In order to iterate over an array, you can also use array get:

    foreach {key val} [array get yourarray] {
    puts "$key = $val"
    }

    which should be more readable.

    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to [email protected] on Wed Nov 16 16:20:18 2022
    At Wed, 16 Nov 2022 11:42:56 -0300 Luc <[email protected]> wrote:


    I am really struggling with this:

    --------------------
    package require Tk

    text .t -width 40 -height 6 -font "FreeSans 18"
    pack .t

    array set file_1 {name file1 date today size 100k}
    array set file_2 {name file2 date today size 200k}
    array set file_3 {name file3 date today size 300k}

    proc p.printfiles argNumber {
    .t delete 1.0 end
    .t insert end ::file_$argNumber
    .t insert end "\n"
    .t insert end "parray: [parray ::file_$argNumber]"
    .t insert end "[set ::file_[set argNumber](size)]"
    parray ::file_$argNumber
    }

    p.printfiles 2
    --------------------

    Result:
    ::file_2
    argNumber
    parray:
    200k

    I've tried all kinds of formats and escaping and can't get the code to
    insert the output of [parray] into the text widget.


    And the plot thickens. If I include [info vars] in those insert lines, the only var it finds is argNumber. What about the global vars? Where are they?

    Maybe that is why it can't print [parray]?

    No, that is not the reason because

    1) the parray line at the end works fine in stdout.

    2) this line works as expected:

    .t insert end "[set ::file_[set argNumber](size)]"

    What am I doing wrong?

    The parray function is *hard wired* to *print* an array to stdout. It is really only meant to debugging use. You will need to write your own parray-like proc to insert the array into the text widget in the format you like. Maybe something like:

    proc insertArray {textwidget arrayname {pattern *}} {
    upvar $arrayname array
    set l 0
    foreach k [array names array $pattern] {
    set l [expr {max($l,[string length $k])}]
    }
    foreach k [array names array $pattern] {
    set space [string repeat " " [expr {$l-[string length $k]}]]
    $textwidget insert end [format "%s(%s)%s = %s\n" \
    $arrayname $k "$space" $array($k)]
    }
    }


    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    [email protected] -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Wed Nov 16 17:27:58 2022
    * Luc <[email protected]>
    | foreach i [array names ::file_$argNumber] {
    | .t insert end "[set ::file_[set argNumber]($i)]\n"
    | }

    | A little ugly and hard to read, but it works.

    May I suggest

    foreach {key val} [array get ::file_$argNumber] {
    .t insert end "$val\n"
    }

    Prettier, IMHO ;-)

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Luc on Wed Nov 16 17:32:45 2022
    Luc <[email protected]> wrote:
    proc p.printfiles argNumber {
    .t delete 1.0 end
    .t insert end ::file_$argNumber
    .t insert end "\n"
    .t insert end "parray: [parray ::file_$argNumber]"
    .t insert end "[set ::file_[set argNumber](size)]"
    parray ::file_$argNumber
    }

    And the plot thickens. If I include [info vars] in those insert
    lines, the only var it finds is argNumber. What about the global
    vars? Where are they?

    As no one has yet answer this, I'll add.

    The reason 'info vars' only shows argNumber is because this is how
    'info vars' is defined to behave:

    man n info:

    info vars ?pattern?
    If pattern is not specified, returns a list of all the
    names of currently-visible variables. This includes
    locals and currently-visible globals. ...

    Do recall that in Tcl, global variables are not visible inside proc's
    by default. Since your proc has a single arg (argNumber) and no calls
    to "global" to make any globals visible, the only 'currently-visible
    variables' inside the proc is the single 'argNumber'.

    If you want to see all the globals, you have to ask for all the
    globals:

    man n info:

    info globals ?pattern?
    If pattern is not specified, returns a list of all the
    names of currently-defined global variables. Global
    variables are variables in the global namespace. ...

    You want 'info globals' if you want to see all the globals from inside
    a proc.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Luc@21:1/5 to Christian Gollwitzer on Wed Nov 16 14:16:44 2022
    On Wed, 16 Nov 2022 17:30:56 +0100, Christian Gollwitzer wrote:

    Am 16.11.22 um 16:54 schrieb Luc:
    Thank you for the clarifications.

    I am doing

    foreach i [array names ::file_$argNumber] {
    .t insert end "[set ::file_[set argNumber]($i)]\n"
    }

    A little ugly and hard to read, but it works.

    In order to iterate over an array, you can also use array get:

    foreach {key val} [array get yourarray] {
    puts "$key = $val"
    }

    which should be more readable.

    Christian


    Yes, I wrote my own syntatic sugar:

    proc p.fileinfo {argNumber argInfo} {
    if {$argInfo == "all"} {
    return "[set ::files_[set argNumber](name) \
    [set ::files_[set argNumber](size) \
    [set ::files_[set argNumber](datetime) \
    [set ::files_[set argNumber](type) \
    [set ::files_[set argNumber](permission)"
    }
    return "[set ::files_[set argNumber]($argInfo)]"
    }


    % puts [p.fileinfo 15 size]
    256636


    Thank you again!

    --
    Luc


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et4@21:1/5 to Helmut Giese on Wed Nov 16 12:09:01 2022
    On 11/16/2022 7:29 AM, Helmut Giese wrote:

    - look into the file 'parray.tcl' (on my installation it is located in
    <path to my installation>/lib/tcl8.6


    Regarding parray, it also nicely formats the output and takes a pattern.

    It also does a sort, however I find it's a bit ugly IMHO with numerical indices. So, I modify it to use a -dictionary sort rather than the default -ascii where 10 sorts before 2.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Griffiths@21:1/5 to Helmut Giese on Wed Nov 16 13:45:54 2022
    On Wednesday, 16 November 2022 at 15:29:17 UTC, Helmut Giese wrote:
    Hi Luc,
    no, you cannot 'parray into a text widget':
    'parray' writes to stdout and a text widget wants
    '$t insert <index where> <text>'.
    I think the simplest solution is:
    - look into the file 'parray.tcl' (on my installation it is located in
    <path to my installation>/lib/tcl8.6
    - rename the parray function, add another parameter to it
    and replace the line 'puts stdout ...' with '$t insert ...'

    HTH
    Helmut

    After a little introspection in the console to see how [parray works]:

    catch {parray ;# command is only autoloaded on demand}
    # You could build the arglist here programatically, but if it's ever changed to be different, the [string map] will likely be out of date too anyway
    proc tarray {a textWidget {pattern *}} [string map [list "puts stdout" "\$textWidget insert end {\n} {} "] [info body parray]]

    array set myArray [list foo bar baz boing]

    parray myArray
    tarray myArray $textWidget

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Thu Nov 17 11:28:12 2022
    * Luc <[email protected]>
    | proc p.fileinfo {argNumber argInfo} {
    | if {$argInfo == "all"} {

    NB. Using 'eq' instead of '==' saves some CPU cycles when TCL is trying
    a numerical comparison first with "==".

    | return "[set ::files_[set argNumber](name) \
    | [set ::files_[set argNumber](size) \
    | [set ::files_[set argNumber](datetime) \
    | [set ::files_[set argNumber](type) \
    | [set ::files_[set argNumber](permission)"
    | }
    | return "[set ::files_[set argNumber]($argInfo)]"
    | }

    If you will ever use this function for other purposes than printing the
    result, like in

    lassign [p.fileinfo foo all] name size datetime type permission

    I would strongly suggest to use [list] to build the return value
    in the 'all' case. Otherwise it's a data-dependent bug waiting to
    happen if some array(name) or any other field contains spaces.

    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)