Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

I have a scope problem I cannot fig 1

Status
Not open for further replies.

marsd

IS-IT--Management
Apr 25, 2001
2,218
US
I have a scope problem I cannot figure out.

The global var is declared inside a proc and is
visible outside the procedure, but does not get processed by the switch -- $var.

ex:

if {[string match "debug" $argv]} {

puts "Debug enabled." ; sleep 1s
exp_internal 1

} else {

send_user "No debug.\n"
}

proc mount_ {} {
set timeout -1
global target

puts "

1. Floppy
2. CDROM
3. Other
4. unmount
5. Exit
"

send_user "YOUR CHOICE: "
expect_user -re "\[0-9]+\n"
set target $expect_out(0,string)
string trimright $target "\n"

}


send_user "Menu UP."
mount_

#tshoot
puts $target

switch -- $target "1" {
exec mount /dev/fd0
set target "/dev/fd0"

} "2" {
exec mount /dev/cdrom
set target "/dev/cdrom"

} "3" {
exec mount /dev/$target
} "4" {
umount $target

} "5" {
exit

}

Very simple, but switch nevers see the var, even though
the variable is exported from the procedure.
Strange.
 
This was a tricky one. It isn't a scoping problem, it's a string manipulation problem. Specifically:

Code:
    string trimright $target "\n"

This is a no-op. All string commands (with the exception of append) do not change the value of their input; they simply give you a return value. Since you're not running your string trimright in a subcommand, its return value is discarded. The value of target is still something like [ignore]"3\n"[/ignore]. Then, when you get to your switch statement, your pattern "3" doesn't match your pattern [ignore]"3\n"[/ignore].

As I say in my classes, with the exception of append and lappend, all string and list command must be executed as subcommands. It's easy to forget, though.

So, in your example, the quick fix would be to change that line to:

Code:
    set target [string trimright $target "\n"]

However, since you're already using a regular expression for your expect pattern, there's a better way: use a capturing subpattern in your regular expression. After all, your expect command is already doing regular expression processing; you might as well have it parse your data for you while you're at it. Thus, you'd completely delete your string trimright line and change the preceding 2 lines to:

Code:
    expect_user -re "(\[0-9]+)\n"
    set target $expect_out(1,string)

For those who haven't used this feature before, a quick explanation. Pieces of a regular expression enclosed in parentheses are called subpatterns. When the expect command successfully matches a regular expression pattern, it stores the characters that matched the entire pattern in the array element expect_out(0,string). It then stores all the characters that matched the first subpattern in expect_out(1,string), all the characters that matched the second subpattern in expect_out(2,string), and so on. (expect can handle up to 9 subpatterns in a regular expression in this manner. Any additional subpatterns are handled correctly in terms of the actual pattern matching, but the characters matching subpatterns 10 and beyond aren't split out separately. This is rarely a problem.) - Ken Jones, President
Avia Training and Consulting
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
That is pretty bizarre. It makes sense and it works, but
the $target var returned a "3" outside the proc scope
through puts $target after the proc call, so I was pretty
confused.
Thanks.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top