Showing posts with label Scripting Languages. Show all posts
Showing posts with label Scripting Languages. Show all posts

August 16, 2012

Passing Arguments to an User-Defined Proc in Tcl

Passing arguments to any procedure is a very common scripting style. In this post we will discuss two ways one can pass arguments to any procedure in Tcl.

Just like the last post, Reading from and writing to a file in Tcl, the text in black represents tcl commands. Text in red represents user-defined variables.

The conventional way to pass arguments to a user-defined procedure (palindrome, in this case) in Tcl is:

proc palindrome { arg1 arg2 } {
<body of the proc using $arg1 and $arg2>
}

The above proc is then called like: palindrome <arg1> <arg2>

The order of passing these arguments need to be maintained.
The above approach works fine. However, when the number of arguments is large, one needs to remember the relevance of each argument and their order of occurrence.

Here's a more versatile way of passing the arguments:

 proc palindrome { args } {
    variable args_list {}
    set valid_switches [list "-description_arg1" "-description_arg2"]
    parse_proc_args $args $valid_switches palindrome

    set arg1           [cdr [assoc "description_arg1"          $args_list]]
    set arg2           [cdr [assoc "description_arg2"          $args_list]]
<body of the proc using $arg1 and $arg2>
}

The above proc is called like: palindrome -description_arg1 <arg1> -description_arg2 <arg2>


Here you can always associate the "description_arg1" keyword with arg1 and so on. Moreover, it is not necessary to call arg1 before arg2.
You can also use: palindrome -description_arg2 <arg2> -description_arg1 <arg1>
  All you gotta make sure is that you associate the arguments with the corresponding description switch!

July 01, 2012

Reading from and writing to a file in Tcl

File handling operations like reading from and writing to a file in any programming language is one of the most commonly used operations.

Writing to a file in Tcl is straightforward. 
In this post, we will discuss two ways to read a file in Tcl:

Note that the text in black represents tcl commands. Text in red represents user-defined variables and comments are in blue.

  1. set in_file [open palindrome_in.csv r]          ## Opens the file palindrome_in.csv in read mode
    set out_file [open palindrome_out.csv w]    ## Opens the file palindrome_out.csv in write mode
    set data [read $in_file]                                   ## "data" now has contents of the input file
    set lines [split $data "\n"]                             ## "lines" now contain collection of lines
    foreach line $lines {                                     ## Reading each "line" from collection of "lines"
    <body of your proc>                                    ## Body of the proc
    }
    puts $out_file "xyz"                                       ## Printing the desired output in palindrome_out.csv
    close $out_file                                              ## Closing the output file
    close $in_file                                                 ## Closing the input file


    Note: Closing both the input and output files is important. If not done, your Tcl shell might return an error "too many open files". Or even worse, the output in the output file might get terminated pre-maturely.
  2. set in_file [open palindrome_in.csv r]            ## Opens the file palindrome_in.csv in read mode
    set out_file [open palindrome_out.csv w]      ## Opens the file palindrome_out.csv in write mode
    while { [gets $in_file line] >= 0 } {                   ## Note that here "line" is not a user-defined variable
    <
    body of your proc>                                       ## Body of the proc
    }
    puts $out_file "xyz"                                       ## Printing the desired output in palindrome_out.csv
    close $out_file                                              ## Closing the output file
    close $in_file                                                 ## Closing the input file
    What's the difference between the two? Well, not much, if the size of your input file in small. However, if it is a big file (for example: SDF files, where the file maybe as big as 1 GB!!), you might prefer using the second method.

    In the first method, the user-defined variable lines contain all the lines of the file in form of a collection. If file is too big, this collection would be too big and one variable will have to hold this fairly big data till your script is working. This might lead to "stack-overflow error".
    This problem is alleviated in the second way where you are reading each line on the go.