help-formatter#add-argument! についてなにか書いてみる
比較的よく書けたな〜って思う help-formatter-add-argument!
について書いてみる。
(define-method help-formatter-add-argument! ((self <help-formatter>) (action <argument-action>)) (unless (equal? (help-of action) +suppress+) (let* ((get-invocation# (ref self format-action-invocation)) (invocations# (hash-table-get get-invocation# action))) (map (lambda (subaction) (push! invocations# (hash-table-get get-invocation# subaction))) (help-formatter-iter-indented-subactions self action)) ;; アイテムの最大長を更新します。 (let* ((invocation-length# (fold max 0 (map string-length invocations#))) (action-length# (+ invocation-length# (ref current-indent self))) (action-max-length# (ref action-max-length self))) (set! (ref action-max-length self) (max action-max-length# action-length#))) (help-formatter-add-item! self (ref format-action self) `(action)))))
define-method
は後で書くことにして (equal? (help-of action) +suppress+)
について。
unless
で囲まれているので、(help-of action)
の戻り値が +suppress+
じゃない場合に以降の処理を評価する。
+suppress+
のような + のイヤーマフ*1の付いたシンボルは定数*2であることを示す。
この定数は argparse.scm のかなり上の方で定義されており:
(define-constant +suppess+ "==SUPPRESS==")
となっている。
これがどういった意味を持つのかは不明。
let
変数の末尾の # は Clojure がそう書いていたので書いてみた。
今気づいたんだけど、get-invocation#
の:
(ref self format-action-invocation)
は:
(help-formatter-format-action-invocation self action)
なんじゃないかと思ってきた。
でも、見なおしたら違ったので format-action-invocation
というスロットを新たに書かないといけない。
次の:
(map (lambda (subaction) (push! invocations# (hash-table-get get-invocation# subaction))) (help-formatter-iter-indented-subactions self action))
は Ruby で書くと:
self.indented_subactions.map do |subaction| invocations.push get_invocation[subaction] end
とおそらく同じ。
おそらくなのは help-formatter-iter-indented-subactions
を書いていないのでw
get-invocation#
が lambda
だってことも考えられるのでうにょーん。
help-formatter-iter-indented-subactions
はインデントされているサブアクションをのリストを返しそうなので map
にしたんだけど…違うおそれもあるよね……( ◞‸◟)
itr
とか書いてあるし…δ(・ω・`)ウーン…
それじゃ次:
;; アイテムの最大長を更新します。 (let* ((invocation-length# (fold max 0 (map string-length invocations#))) (action-length# (+ invocation-length# (ref current-indent self))) (action-max-length# (ref action-max-length self))) (set! (ref action-max-length self) (max action-max-length# action-length#)))
invocation-length#
の値である (fold max 0 (map string-length invocations#))
は何をするか分かるかな?
(l ω l〃) わかるー!
╰( ´◔ ω ◔ `)╯ そりゃお前はな…
じゃあ、サンプルコード:
(let ((invocations '("help" "version" "quiet" "verbose"))) (fold max 0 (map string-length invocations)))
は文字列のリストの各要素の文字列長で最大の値を返すよ。
7
まあ、そんな感じで。