• Does tcl has something like Java try with resources?

    From Cecil Westerhof@21:1/5 to All on Wed Dec 8 17:31:21 2021
    In Java you can use try with resources to open a file (resource) and
    you do not have to take care of the closing of the file. Does tcl has
    something like that?

    If not is the following a good way to simulate it partly. (I count on
    it that there will be no problem with the read.)
    if {[catch {set speedtestFP [open ${speedtestCmd} RDONLY]} openError]} {
    puts stderr "Could not start speedtest (${openError})"
    return
    }
    for {set i 0} {$i < 1} {incr i} {
    gets ${speedtestFP} pingLine
    if {[regexp ${checkPing} ${pingLine} -> ping] != 1} {
    puts stderr "Could not get the ping value (${pingLine})"
    break
    }
    gets ${speedtestFP} downloadLine
    if {[regexp ${checkDownload} ${downloadLine} -> download] != 1} {
    puts stderr "Could not get the download value (${downloadLine})"
    break
    }
    gets ${speedtestFP} uploadLine
    if {[regexp ${checkUpload} ${uploadLine} -> upload] != 1} {
    puts stderr "Could not get the upload value (${uploadLine})"
    break
    }
    showMessage "${ping} ${download} ${upload}" True
    storeSpeedtestDo ${ping} ${download} ${upload} \
    ${::speedtestSleep} ${::intervalSpeedtest}
    }
    if {[catch {close ${speedtestFP}} closeError]} {
    puts stderr "Could not close speedtest (${closeError})"
    return
    }

    In Java I could just use a return, but I can not leave an open
    file-pointer.

    --
    Cecil Westerhof
    Senior Software Engineer
    LinkedIn: http://www.linkedin.com/in/cecilwesterhof

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Wed Dec 8 18:06:33 2021
    * Cecil Westerhof <Cecil@decebal.nl>
    | In Java you can use try with resources to open a file (resource) and
    | you do not have to take care of the closing of the file. Does tcl has
    | something like that?

    Check the TCL 'try' command:

    https://www.tcl.tk/man/tcl/TclCmd/try.html

    While it does not automagically close the file handle, it allows to
    close it in the 'finally' clause, no matter what. See the 'Examples'
    section in the above manpage.

    HTH
    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Cecil Westerhof@21:1/5 to Ralf Fassel on Wed Dec 8 21:08:23 2021
    Ralf Fassel <ralfixx@gmx.de> writes:

    * Cecil Westerhof <Cecil@decebal.nl>
    | In Java you can use try with resources to open a file (resource) and
    | you do not have to take care of the closing of the file. Does tcl has
    | something like that?

    Check the TCL 'try' command:

    https://www.tcl.tk/man/tcl/TclCmd/try.html

    While it does not automagically close the file handle, it allows to
    close it in the 'finally' clause, no matter what. See the 'Examples'
    section in the above manpage.

    Yes that would work. I have:
    proc tryWithFinally {} {
    try {
    puts "I am in the try"
    return
    } finally {
    puts "Got in the finally"
    }
    }

    tryWithFinally

    and I get:
    I am in the try
    Got in the finally

    It does not work with an exit, but I do not mind that.
    (At the moment.)


    But I have to look further into it. I tried simulating an error with
    an immediate return. Then I get:
    child process exited abnormally

    Probably because I close the process before it is finished.

    --
    Cecil Westerhof
    Senior Software Engineer
    LinkedIn: http://www.linkedin.com/in/cecilwesterhof

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From luocl@21:1/5 to Cecil Westerhof on Thu Dec 9 08:08:15 2021
    On 12/9/21 12:31 AM, Cecil Westerhof wrote:
    In Java you can use try with resources to open a file (resource) and
    you do not have to take care of the closing of the file. Does tcl has something like that?

    There is a package "defer" of tcllib, doing for this purpose.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From heinrichmartin@21:1/5 to Cecil Westerhof on Thu Dec 9 00:04:13 2021
    On Wednesday, December 8, 2021 at 9:14:05 PM UTC+1, Cecil Westerhof wrote:
    It does not work with an exit, but I do not mind that.
    (At the moment.)

    Side-note: you can rename exit to create your own version of it (and your new exit is invoked even if it is not called explicitly)

    expect:/tmp$ namespace eval my {}
    expect:/tmp$ rename exit ::my::exit
    expect:/tmp$ proc exit args {puts gotcha; tailcall ::my::exit $args} expect:/tmp$ ^C
    gotcha

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Emiliano Gavilan@21:1/5 to Cecil Westerhof on Thu Dec 9 08:43:22 2021
    On Wed, 08 Dec 2021 21:08:23 +0100
    Cecil Westerhof <Cecil@decebal.nl> wrote:

    Yes that would work. I have:
    proc tryWithFinally {} {
    try {
    puts "I am in the try"
    return
    } finally {
    puts "Got in the finally"
    }
    }

    tryWithFinally

    and I get:
    I am in the try
    Got in the finally

    It does not work with an exit, but I do not mind that.
    (At the moment.)

    it works with [tailcall]


    $ tclsh
    % proc tryWithFinally {} {
    try {
    puts "I am in the try"
    tailcall exit
    } finally {
    puts "Got in the finally"
    }
    }
    % tryWithFinally
    I am in the try
    Got in the finally
    $


    --
    Emiliano Gavilan

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Thu Dec 9 15:58:11 2021
    * Emiliano Gavilan <emilianogavilan@gmail.com>
    | $ tclsh
    | % proc tryWithFinally {} {
    | try {
    | puts "I am in the try"
    | tailcall exit
    | } finally {
    | puts "Got in the finally"
    | }
    | }

    Man tailcall(n) says:

    DESCRIPTION
    The tailcall command replaces the currently executing procedure,
    lambda application, or method with another command.
    [...]
    This command may not be invoked from within an uplevel into a
    procedure or inside a catch inside a procedure or lambda.

    I read that as "don't use tailcall inside catch", like this

    # dont:
    catch {
    tailcall ...
    }

    Is it ok to use 'tailcall' in 'try', or is 'try' missing as "don't do
    this" in the documentation?

    R'

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