2013-02-09 47 views
1

的情況下進行擴展我怎樣才能在下面的腳本執行expand(擴大命令和變量,如TCL正常),我希望它打印出來:如何在字符串中調用函數的TCL

' 
    hello { 
     $b 
    } 
    {tcl world} 
' 

這就是我想象中的腳本將看:

proc clever_func {script} { 
    set script [uplevel 1 expand [list $script]] 
    puts "'$script'" 
} 

proc isolated_client_function {} { 
    set a hello 
    set b difficult 
    set c tcl 
    set d world 

    clever_func { 
     $a { 
      $b 
     } 
     [list $c $d] 
    } 
} 

isolated_client_function 

回答

2

一個例子是不足夠的替代品的規範,但似乎沒有內置的TCL工廠做你想要什麼。可以在單個命令尾部(通過將list添加到某個命令並將eval添加到您希望的任何級別)進行替換,但不能對具有兩個「命令」的僞腳本執行替換。 (也可以使用subst做字符串插值,但您可能已經知道它爲什麼不是您想要的:它也將擴展爲$b)。

我看到兩種可能得到你想要的東西:

  1. 記號化使用sugar::scriptToList您的輸入,然後在標記列表中手動執行替換,然後將結果轉換回文本形式sugar::listToScriptsugar宏處理器的這些功能旨在讓您在保留格式,註釋和佈局的同時語義上修改腳本。

  2. 打破你輸入成單獨的「命令」:先拆每個換行和分號,然後用info complete收集完成相應「命令」件(IIRC會有一些角落例反斜槓換行符延續:當心)。在每個完整的「命令」中,使用前面加上"list "的技巧,在必要的上下文中評估結果(uplevel)。因此,對於每個命令,您將得到一個列表,其中在適用時已經執行了替換。每個「命令」內部都會失去格式的細微差別(比如分隔單詞和空間類型的空格數量),並且除非您自己記住它們,否則將失去原始命令分隔符。如果您的目標是在稍後的某個其他環境中獲得一種「預擴展腳本」,則對您而言可能並不壞。

+0

謝謝您的回答@安東·科瓦連科。我只會在我的示例中使用$ script變量來執行命令(不是像我爲了討論某些內容所做的那樣打印它們),所以如果有方法將$ script轉換爲第一個命令在'uplevel'下執行,我可以將餘數(第二,第三等命令)分配回$ script,然後重複,然後我將成爲一個非常快樂的兔子。 – codeshot 2013-02-10 00:21:36

+0

我發現你鏈接的糖文檔頁面非常難讀。有沒有更清晰的參考資料? – codeshot 2013-02-10 00:55:11

+0

解析是實現預期效果的唯一方法。另外兩個頁面是[tclparser](http://wiki.tcl.tk/1660)和[parsetcl](http://wiki.tcl.tk/9649);我不知道哪個更容易基於。 (使用'info complete'只是「解析」的一個變種。) – 2013-02-10 13:16:04

1

subst命令將帶你到那裏的大部分。

proc expand {script} { 
    uplevel 1 [list subst $script] 
} 

set a hello 
set b difficult 
set c tcl 
set d world 

expand { 
    $a { 
     $b 
    } 
    [list $c $d] 
} 

輸出

hello { 
     difficult 
    } 
    tcl world 

我不知道把我的頭頂部如何防止$b被取代。您可能必須自己解析腳本。

如果你想在最後一部分有你展示報價,你需要列表岬的另一個層面

expand { 
    $a { 
     $b 
    } 
    [list [list $c $d]] 
} 

輸出

hello { 
     difficult 
    } 
    {tcl world} 
+0

感謝您的回答。我只以爲我需要額外的引用級別,因爲字符串實際上將用作腳本,在名稱空間eval下執行 - 這意味着它將再次展開,因此我需要在clever_func中添加額外的引號。 – codeshot 2013-02-10 08:09:35

相關問題