NAME
perlform - Perl 格 式
DESCRIPTION 描 述
Perl的 一 些 內 部 機 制 、 可 以 幫 助 我 們 產 生 一 份 簡 單 的 格 式 化 圖 表 。 經 過 perl的 處 理 , 你 列 印 的 格 式 可 以 接 近 於 你 所 見 的 外 貌 。 它 可 以 記 錄 如 你 現 在 正 處 在 哪 個 頁 面 , 每 個 頁 面 的 行 數 與 何 時 列 印 出 頁 面 的 標 題 。 關 鍵 字 , format() 格 式 函 數 與 write()執 行 函 數 是 直 接 引 自 FORTRAN語 法 。 詳 情 可 參 閱 perlfunc。 幸 運 的 是 列 印 的 格 式 可 讀 性 又 有 所 提 高 。 幾 乎 類 似 BASIC 的 PRINT USING。 可 以 把 它 想 象 爲 簡 單 的 nroff(1). 有 如 子 程 序 與 包 一 樣 , 格 式 只 是 語 句 的 聲 明 , 而 不 是 執 行 調 用 。 故 它 可 以 放 在 程 式 的 任 何 位 置 ( 一 般 最 好 是 把 它 們 集 中 在 一 塊 ) 。 與 perl的 其 它 變 量 名 字 類 型 不 同 , 格 式 命 名 有 別 於 一 般 的 獨 自 的 定 義 。 也 就 是 說 , 你 有 一 個 名 爲 Foo的 函 數 , 它 與 另 一 個 格 式 名 稱 爲 Foo的 東 西 是 完 全 不 同 。 但 是 缺 省 的 格 式 名 稱 與 有 關 連 的 文 件 句 柄 可 用 相 同 的 名 字 。 所 以 缺 省 的 輸 出 格 式 名 稱 STDOUT, 它 的 文 件 句 柄 名 稱 就 是 STDOUT。 而 對 缺 省 格 式 名 稱 TEMP, 它 的 文 件 句 柄 名 稱 也 可 以 是 TEMP。 雖 然 名 稱 一 樣 但 兩 者 並 不 相 同 。 輸 出 格 式 的 語 法 如 下 :
format NAME = FORMLIST .如 省 略 格 式 名 稱 , 格 式 名 稱 將 以 標 準 輸 出
STDOUT命 名 。 而 格 式 項 目 將 包 括 了 好 幾 個 連 續 橫 行 。 每 一 行 屬 於 下 列 叄 種 型 態 之 一 :
1. 註 釋 ( |
comment), 以 符 號 “#”置 於 每 行 的 開 頭 。 |
|||
2. 圖 案 行 |
(picture line), 規 定 了 單 一 行 的 格 式 化 外 觀 。 , 提 供 一 些 數 值 以 對 應 前 面 的 圖 案 行 。 圖 案 行 的 輸 出 效 果 就 與 我 們 看 到 的 一 樣 , 除 了 某 些 值 域 欄 位 會 給 相 對 應 數 值 取 代 外 , 每 個 輸 入 欄 位 都 以 一 個 @或 ^ 控 制 符 開 頭 。 這 些 單 行 內 的 控 制 符 不 能 做 任 何 竄 改 取 代 (勿 與 數 組 變 量 @混 淆 )。 @欄 位 是 屬 於 正 常 形 態 的 欄 位 , 而 ^欄 位 則 用 來 表 示 可 以 輸 入 多 行 文 字 。 至 於 該 欄 位 則 由 < > 或 ⎪ 符 號 跟 隨 其 後 指 定 向 左 、 右 、 或 居 中 對 齊 。 並 同 時 跟 據 該 符 號 的 數 目 , 輸 入 指 定 資 料 的 長 度 。 如 變 量 內 容 超 過 限 定 長 度 、 格 式 列 印 時 會 自 動 刪 除 多 餘 的 部 份 。 另 一 種 指 定 向 右 對 齊 方 式 , 是 使 用 #符 號 來 指 定 一 個 數 字 欄 位 。 如 此 可 方 便 小 數 點 定 位 。 如 果 輸 入 值 裏 還 包 含 一 個 換 行 字 元 (0, 則 僅 列 印 出 該 換 行 字 元 前 的 資 料 。 最 後 圖 案 行 出 現 的 @*這 個 特 別 符 號 標 記 , 可 以 用 來 列 印 多 行 並 且 不 被 截 掉 的 數 值 。 接 下 來 的 一 行 、 是 跟 據 圖 案 行 裏 的 值 域 欄 位 輸 入 相 應 的 數 值 。 如 果 是 利 用 運 算 式 提 供 數 值 的 話 、 必 須 以 逗 號 分 隔 。 因 爲 所 有 的 表 示 法 都 會 被 當 成 一 個 串 連 內 容 再 行 處 理 。 所 以 一 個 單 一 的 串 列 表 示 法 也 可 產 生 多 個 串 列 資 料 。 如 果 表 示 法 是 利 用 括 號 圍 起 , 可 能 會 展 開 好 幾 行 。 若 想 如 是 安 排 , 第 一 行 的 第 一 個 單 字 必 須 是 以 左 括 號 開 始 。 如 果 運 算 式 內 有 小 數 點 的 數 字 類 型 須 要 處 理 、 同 時 圖 案 行 的 相 關 符 號 也 指 出 小 數 位 須 列 印 出 來 (除 了 圖 案 行 內 的 包 含 小 數 點 "."的 數 字 控 制 符 號 #外 )。 小 數 點 列 印 出 的 外 貌 , 以 當 地 的 運 行 版 本 決 定 (LC_NUMERIC locale)。 也 就 是 說 、 在 德 文 地 區 使 用 小 數 格 示 輸 出 時 、 小 數 點 的 顯 示 將 是 ","而 非 "."。 相 關 資 料 請 參 考 perllocale 與 "警 告 " 圖 案 行 裏 的 欄 位 如 果 以 ^控 制 符 開 頭 、 格 式 將 會 作 特 殊 化 處 理 。 如 果 該 欄 位 是 註 解 欄 位 又 沒 定 義 其 值 、 欄 位 將 以 空 白 取 代 。 若 是 其 它 型 態 、 則 視 爲 一 種 填 補 資 料 的 狀 態 。 在 此 、 我 們 不 能 隨 便 填 入 任 意 表 示 法 進 去 。 相 反 、 必 須 以 相 關 的 變 量 輸 入 字 串 內 容 。 perl會 盡 量 將 文 字 放 入 該 欄 位 、 然 後 把 字 串 的 前 面 部 份 刪 去 。 當 你 下 次 使 用 該 字 串 變 量 時 、 可 以 使 用 後 面 的 字 串 部 份 (換 句 話 說 、 在 執 行 write函 數 時 、 字 串 變 量 的 內 容 是 會 改 變 的 )。 正 常 情 況 下 、 你 必 須 使 用 一 類 似 垂 直 狀 的 堆 塊 來 放 置 要 輸 入 的 文 字 、 以 便 整 齊 列 印 出 一 柱 狀 文 字 。 如 你 列 印 的 文 字 太 長 、 想 以 "..."取 代 過 長 的 文 字 時 、 你 可 以 藉 由 更 改 $: 變 量 值 來 取 代 分 隔 字 元 。 也 就 是 當 你 使 用 ENGLISH模 塊 時 的 $FORMAT_LINE_BREAK_CHARACTERS的 意 思 。 使 用 ^符 號 欄 位 可 產 生 不 定 長 度 的 記 錄 欄 位 。 如 果 要 列 印 的 文 字 很 短 、 你 想 壓 縮 掉 文 字 後 的 空 白 、 請 在 想 壓 縮 掉 的 空 白 地 方 加 上 一 個 "~"控 制 符 號 。 如 果 重 複 使 用 兩 個 "~"符 號 、 則 該 行 會 被 重 複 列 印 、 直 到 該 欄 位 的 所 有 文 字 列 印 完 畢 爲 止 (如 你 同 時 使 用 "@"值 域 欄 位 的 話 、 切 記 每 次 要 輸 入 不 同 的 數 值 )。 列 印 格 示 標 題 的 缺 省 處 理 方 法 、 是 將 正 使 用 的 格 式 名 稱 後 加 上 _TOP字 樣 既 可 。 其 內 容 將 會 列 印 至 每 頁 的 開 頭 部 份 。 請 參 考 perlfunc/write 函 數 例 如 : # a report on the /etc/passwd file format STDOUT_TOP = Passwd File Name Login Office Uid Gid Home ------------------------------------------------------------------ . format STDOUT = @<<<<<<<<<<<<<<<<<< @⎪⎪⎪⎪⎪⎪⎪ @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<< $name, $login, $office,$uid,$gid, $home . # a report from a bug report form format STDOUT_TOP = Bug Reports @<<<<<<<<<<<<<<<<<<<<<<< @⎪⎪⎪ @>>>>>>>>>>>>>>>>>>>>>>> $system, $%, $date ------------------------------------------------------------------ . format STDOUT = Subject: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $subject Index: @<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $index, $description Priority: @<<<<<<<<<< Date: @<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $priority, $date, $description From: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $from, $description Assigned to: @<<<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $programmer, $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<< $description ~ ^<<<<<<<<<<<<<<<<<<<<<<<... $description .我 們 也 有 可 能 在 同 一 個 輸 出 管 道 同 時 使 用 print 與 write函 數 。 但 使 用 時 、 必 須 修 改 $-的 特 殊 內 置 變 量 值 (使 用 English模 塊 的 話 、 則 是 使 用 $FORMAT_LINES-LEFT變 量 )。 Format Variables 格 式 變 量 當 前 的 格 式 名 稱 一 向 都 是 存 放 於 $~這 個 特 殊 變 量 內 ($FORMAT_NAME), 而 每 頁 的 開 頭 格 式 則 存 放 在 $^($FORMAT-TOP_NAME), 輸 出 頁 爲 $%($FORMAT_PAGE_NUMBER), 每 頁 行 數 是 $= ($FORMAT_LINE_PER_PAGE), 自 動 輸 出 格 式 是 放 在 $⎪($OUTPUT_AUTOFLUSH)、 要 輸 出 到 每 頁 開 頭 部 份 的 字 串 存 放 在 $^L ($FORMAT-FORMFEED)。 這 些 變 量 的 有 效 範 圍 , 都 是 以 某 一 個 文 件 句 柄 爲 單 元 。 因 此 、 你 必 須 調 用 select()函 數 來 調 用 適 當 的 文 件 句 柄 來 改 變 變 量 內 容 。 select((select(OUTF), $~ = "My_Other_Format", $^ = "My_Top_Format" )[0]);難 看 吧 ! 這 就 是 一 般 用 法 。 如 此 一 來 、 你 至 少 可 用 臨 是 變 量 來 存 放 前 一 個 文 件 句柄 。 事 實 上 、 這 已 是 較 好 的 作 法 , 除 了 可 讀 性 提 高 外 、 也 提 供 你 一 個 位 置 暫 停 程式 的 執 行 , 方 變 你 一 次 到 位 除 錯 。 $ofh = select(OUTF); $~ = "My_Other_Format"; $^ = "My_Top_Format"; select($ofh);如 果 你 使 用 English模 塊 , 你 甚 至 可 以 輸 入 英 文 變 量 名 稱 use English ’-no_match_vars’; $ofh = select(OUTF); $FORMAT_NAME = "My_Other_Format"; $FORMAT_TOP_NAME = "My_Top_Format"; select($ofh);但 你 還 是 要 調 用 select()函 數 。 因 此 我 們 建 議 你 用 FileHandle模 塊 。 現 在 你 可 用 小 寫 英 文 字 母 的 格 式 名 稱 來 處 理 這 些 特 殊 變 量 。 use FileHandle; format_name OUTF "My_Other_Format"; format_top_name OUTF "My_Top_Format";好 多 了 吧 ! NOTES因 爲 數 值 行 的 內 容 可 能 保 括 任 何 的 表 示 法 (我 們 指 的 是 @ 欄 位 而 非 ^ 欄 位 )。 因 此 你 可 使 用 其 它 函 數 、 建 立 更 加 複 雜 的 處 理 方 法 。 好 像 使 用 printf 函 數 、 或 自 己 定 義 的 函 數 。 列 如 : format Ident = @<<<<<<<<<<<<<<< &commify($n) .在 欄 位 輸 入 真 正 的 @ 或 ^符 號 : format Ident = I have an @ here. "@" .將 整 行 字 置 中 對 齊 : format Ident = @⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪ "Some text line" .我 們 並 無 任 何 內 建 的 方 法 讓 你 指 定 如 、 某 個 欄 位 要 對 齊 該 頁 面 最 右 等 諸 如 此 類 事項 。 但 你 仍 然 能 列 印 出 你 想 要 的 格 式 。 跟 據 目 前 頁 面 直 行 數 目 , 調 用 eval()函 數 來 處 理 它 : $format = "format STDOUT = \n" . ’^’ . ’<’ x $cols . "\n" . ’$entry’ . "\n" . "\t^" . "<" x ($cols-8) . "~~\n" . ’$entry’ . "\n" . ".\n"; print $format if $Debugging; eval $format; die $@ if $@;它 可 能 列 印 出 下 列 格 式 外 貌 : format STDOUT = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $entry ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ $entry .下 面 是 一 個 有 點 類 似 fmt(1)的 小 程 式 : format = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ~~ $_ . $/ = ’’; while (<>) { s/\s*\n\s*/ /g; write;} Footers 頁 腳 雖 然 我 們 有 $FORMAT_TOP_NAME來 記 錄 每 頁 開 頭 部 份 的 格 式 , 卻 沒 有 一 個 相 對 應 的 方 法 來 自 動 指 定 每 頁 的 底 部 格 式 。 問 題 是 、 我 們 並 不 知 到 某 個 格 式 資 料 可 能 會 多 大 , 除 非 你 真 的 去 執 行 它 。 這 是 我 們 將 來 要 處 理 的 重 點 之 一 。 這 是 一 個 暫 時 的 應 用 方 案 如 果 你 有 一 個 固 定 大 小 的 頁 腳 、 你 可 在 每 次 調 用 write函 數 前 檢 查 變 量 $FORMAT_LINES_LEFT, 然 後 自 行 印 出 該 資 料 。 還 有 一 個 方 法 , 就 是 開 啓 一 個 管 道 。 調 用 open(MYSELF,”⎪-”) (參 考 perlfunc/open() 函 數 )。 並 調 用 write函 數 把 資 料 輸 往 MYSELF、 而 不 是 標 準 輸 出 STDOUT。 然 後 利 用 子 串 列 的 標 準 輸 入 、 來 重 新 處 理 每 頁 開 頭 或 結 尾 所 要 附 加 的 資 料 部 份 。 這 雖 不 方 便 , 但 還 是 可 辦 到 的 。 Accessing Formatting Internals 格 式 處 理 的 核 心 至 於 低 階 格 式 的 機 制 , 你 可 調 用 formlin()函 數 直 接 處 理 $^A變 量 ($ACCUMUNATOR)。 例 如 : $str = formline <<’END’, 1,2,3; @<<< @⎪⎪⎪ @>>> END print "Wow, I just stored ’$^A’ in the accumulator!\n";或 是 設 計 一 個 子 程 式 swrite()。 它 對 於 write 的 腳 色 相 當 於 sprint 對 於 print。 use Carp; sub swrite { croak "usage: swrite PICTURE ARGS" unless @_; my $format = shift; $^A = ""; formline($format,@_); return $^A;} $string = swrite(<<’END’, 1, 2, 3); Check me out @<<< @⎪⎪⎪ @>>> END print $string; WARNINGS 警 告不 當 處 理 顯 示 結 束 格 示 內 容 的 點 操 作 符 號 、 有 時 也 會 同 時 影 響 你 的 網 絡 的 電 郵 功 能 (跟 據 過 往 經 驗 、 錯 誤 是 必 然 而 不 能 避 免 )。 如 果 使 用 電 郵 輸 出 格 式 內 容 、 你 應 先 處 理 好 結 束 格 式 點 操 作 符 位 置 。 切 勿 放 置 於 左 邊 界 、 以 免 被 SMTP截 去 。 局 部 變 量 (引 用 ”my”定 義 變 量 )、 在 調 用 格 式 化 輸 出 時 不 會 被 察 覺 。 除 非 在 使 用 局 部 變 量 的 串 程 內 另 行 定 義 (5.001版 本 前 並 沒 有 局 部 變 量 一 詞 )。 格 式 輸 出 是 perl 語 言 裏 維 一 受 制 於 編 程 使 用 地 區 的 部 分 。 如 果 當 前 的 使 用 地 區 使 用 LC_NUMERIC, 那 小 數 點 符 號 的 格 式 化 輸 出 必 以 當 地 方 式 顯 示 。 perl 不 會 理 會 當 地 的 所 須 格 式 , 除 非 你 調 用 了 use locale。 但 格 式 列 印 又 不 受 控 於 use locale。 因 爲 locale 它 只 在 使 用 的 塊 內 有 效 。 同 時 跟 據 歷 史 原 因 、 格 式 的 作 用 域 不 僅 包 括 在 塊 內 。 進 一 步 詳 情 參 閱 perllocale 本 地 化 文 檔 。 格 式 輸 出 時 、 程 式 串 內 的 空 白 符 號 0,相 當 於 一 個 空 白 單 元 。 所 以 你 可 以 想 像 格 式 列 印 相 當 於 先 處 理 變 量 : $value =~ tr/\n\t\f/ /; 將 強 制 性 另 印 新 行 。 除 非 圖 案 行 已 定 義 、 餘 下 的 空 白 符 號 中 文 版 維 護 人小 高 <you [AT] email.com> 中 文 版 最 新 更 新2001年 12月 9日 星 期 日 中 文 手 冊 頁 翻 譯 計 劃http://cmpp.linuxforum.net 跋 本 頁 面 中 文 版 由 中 文 man 手 冊 頁 計 劃 提 供 。 中 文 man 手 冊 頁 計 劃 : https://github.com/man-pages-zh/manpages-zh |