Передача списка процессу tcl

Я уже смотрел список передачи в процедуру Tcl, и я не мог понять, как сделать это правильно. Чтобы выразить это в контексте, вот как я передаю список:

switch $choice {
    n {
        set ptable [new_partition {$ptable}]
    }
    d {
        set ptable [delete_partition {$ptable}]
    }
    p {
        set ptable [print_table {$ptable}]
    }
    w {
        set ptable [write_table {$ptable $fn}]
        puts "Saving file...\nExiting..."
        break
    }
    q {
        puts "Exiting..."
        break
    }
    default {
        puts "Illegal option"
    }
}

Это пример одной из процедур

proc print_table {ptable} {
    # Set format string
    set formatStr {%-16s%-8s%-8s%-8s%-8s%-8s}
    # Print the contents of ptable to stdout
    puts [format $formatStr "\nPartition" "Start" "End" "Blocks" "ID" "System"]
    puts "--------------------------------------------------------"
    foreach item $ptable {
        set parts [lindex $item 0]
        set sCyl [lindex $item 1]
        set eCyl [lindex $item 2]
        set blok [lindex $item 3]
        set id [lindex $item 4]
        set sys [lindex $item 5]
        puts [format $formatStr $parts $sCyl $eCyl $blok $id $sys]
    }
    return $ptable
}

Ptable создается правильно, но теряет всю информацию, как только я передаю ее одной из процедур. Я пробовал передать его с помощью "{*} $ ptable", но он возвращает ошибку. Все остальное в моей программе работает отлично (если я возьму код из любой отдельной процедуры и поставлю его отдельно, все работает), я просто не могу заставить его правильно передать список.


person Peter    schedule 24.03.2016    source источник


Ответы (1)


Не используйте здесь фигурные скобки: new_partition {$ptable} - фигурные скобки запрещают раскрытие переменных, и вы передаете 7-символьную строку $ p t a b l e

См. Правило № 6 в http://tcl.tk/man/tcl8.6/TclCmd/Tcl.htm

Просто передайте переменную: new_partition $ptable

Сходным образом:

delete_partition $ptable
print_partition $ptable
write_partition $ptable $fn

Показанная вами print_table процедура на самом деле не изменяет переданный ей аргумент, поэтому вам действительно не нужно возвращать значение. Кроме того, вам действительно не нужно разбивать строки таблицы ptable на отдельные переменные, если вы просто передаете их в format. Вы можете превратить этот процесс в

# Print the contents of ptable to stdout
proc print_table {ptable} {
    set formatStr {%-16s%-8s%-8s%-8s%-8s%-8s}
    puts [format $formatStr "\nPartition" Start End Blocks ID System]
    puts "--------------------------------------------------------"
    foreach item $ptable {
        puts [format $formatStr {*}$item]
    }
}

И не делай этого

set ptable [print_table $ptable]

но сделай это

print_table $ptable
person glenn jackman    schedule 24.03.2016
comment
Кажется, это хорошо работает для трех процедур, но возникают проблемы с процедурой записи, поскольку мне нужно передать две переменные. Это такой же формат? - person Peter; 25.03.2016
comment
Я только что добавил это к своему ответу - person glenn jackman; 25.03.2016
comment
@Peter Требуется ли какая-либо из ваших процедур обновить список? Если это так, существует другая применимая идиома. - person Donal Fellows; 26.03.2016