如何使用相同格式的tcl智能地将tcl可读格式的变量写回文件
这段代码有一个名为class1的类和set、get、load、save方法如何使用相同格式的tcl智能地将tcl可读格式的变量写回文件,tcl,Tcl,这段代码有一个名为class1的类和set、get、load、save方法 # Class1 definition oo::class create class1 { variable dataArr method set {key value} { set dataArr($key) $value } method get {key} { if {[info exist dataArr($key)]} {
# Class1 definition
oo::class create class1 {
variable dataArr
method set {key value} {
set dataArr($key) $value
}
method get {key} {
if {[info exist dataArr($key)]} {
return $dataArr($key)
}
}
method load {} {
set fp [open /home/karthikc/data.tcl r]
set file_data [read $fp]
puts $file_data
eval $file_data
close $fp
}
method save {{newFilePath ""}} {
if [info exists filePath] {
set tmpFP $filePath
}
if {$newFilePath ne ""} {
set tmpFP $newFilePath
}
if ![info exists tmpFP] {
puts"neither newFilePath argument is passed nor filePath variable is present"
return 0
}
try {
set fhandle [open $tmpFP w]
if ![info exists dataArr] {
puts "dataArr variable doesn't exist in the object [self]"
return 0
}
foreach key [array names dataArr] {
set kvPair [list $key $dataArr($key)]
lappend dataLst $kvPair
puts $fhandle "my set $key $dataArr($key)"
puts "my set $key $dataArr($key)"
}
set filePath $tmpFP
puts "dictionary is successfully saved in the file path"
} on error {result opts} {
puts $result
puts "Return options Directory"
puts $opts
return 0
} finally {
if [info exist fhandle] {
close $fhandle
}
}
return 1
}
}
我是这样使用的:
# create object instance
set obj [class1 new]
# call load method
$obj load
# call save method
$obj save /home/karthikc/data.tcl
我的数据.tcl
是
my set key1 value1
my set key2 value2
my set key3 [list valueA valueB valueC]
my set key4 [list valueX [list valueY valueZ]]
我想写回相同的格式或其他列表我更改了存储列表的格式 从 到 在保存方法中我改变了
puts $fhandle "my set $key $dataArr($key)"
到
而这些变化也达到了目的。改进建议
您可以简化序列化程序,并使其更加健壮
首先,不要将对象的状态序列化为脚本,而是一个文本映射(Tcl中的关联数组或dict)。并这样读:
data.tcl
可能看起来像:
key3 {valueA valueB valueC}
key4 {valueX {valueY valueZ}}
key1 value1
key2 value2
您的load
方法可以使用array set
直接读取以下内容:
method load {} {
set fp [open /tmp/data.tcl r]
set file_data [read $fp]
array set dataArr $file_data
close $fp
}
您的save
方法可以直接使用array get
并生成格式化输出:
method save2 {{newFilePath ""}} {
if {[array exists dataArr]} {
set fhandle [open $newFilePath w]
set out ""
foreach {k v} [array get dataArr] {
append out $k " " [list $v] \n
}
puts $fhandle $out
close $fhandle
}
}
这个想法的关键是避免eval
,从而避免代码注入。序列化格式匹配1:1的一流Tcl数据结构
改进你的问题
请允许我说,你的问题不是一个恰当的问题。它并没有说明问题,人们必须阅读字里行间的内容和片段,才能感觉到你在追求什么。此外,代码示例应该减少到最低限度,以演示您感知到的问题。粘贴整个代码工作是没有帮助的
key3 {valueA valueB valueC}
key4 {valueX {valueY valueZ}}
key1 value1
key2 value2
method load {} {
set fp [open /tmp/data.tcl r]
set file_data [read $fp]
array set dataArr $file_data
close $fp
}
method save2 {{newFilePath ""}} {
if {[array exists dataArr]} {
set fhandle [open $newFilePath w]
set out ""
foreach {k v} [array get dataArr] {
append out $k " " [list $v] \n
}
puts $fhandle $out
close $fhandle
}
}